]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branch 'rcu-v28-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 10 Oct 2008 20:10:51 +0000 (13:10 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 10 Oct 2008 20:10:51 +0000 (13:10 -0700)
* 'rcu-v28-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (21 commits)
  rcu: RCU-based detection of stalled CPUs for Classic RCU, fix
  rcu: RCU-based detection of stalled CPUs for Classic RCU
  rcu: add rcu_read_lock_sched() / rcu_read_unlock_sched()
  rcu: fix sparse shadowed variable warning
  doc/RCU: fix pseudocode in rcuref.txt
  rcuclassic: fix compiler warning
  rcu: use irq-safe locks
  rcuclassic: fix compilation NG
  rcu: fix locking cleanup fallout
  rcu: remove redundant ACCESS_ONCE definition from rcupreempt.c
  rcu: fix classic RCU locking cleanup lockdep problem
  rcu: trace fix possible mem-leak
  rcu: just rename call_rcu_bh instead of making it a macro
  rcu: remove list_for_each_rcu()
  rcu: fixes to include/linux/rcupreempt.h
  rcu: classic RCU locking and memory-barrier cleanups
  rcu: prevent console flood when one CPU sees another AWOL via RCU
  rcu, debug: detect stalled grace periods, cleanups
  rcu, debug: detect stalled grace periods
  rcu classic: new algorithm for callbacks-processing(v2)
  ...

725 files changed:
Documentation/00-INDEX
Documentation/DMA-API.txt
Documentation/DocBook/kernel-api.tmpl
Documentation/SELinux.txt [new file with mode: 0644]
Documentation/block/deadline-iosched.txt
Documentation/cdrom/ide-cd
Documentation/cpu-freq/index.txt
Documentation/hwmon/adt7473
Documentation/hwmon/sysfs-interface
Documentation/kernel-doc-nano-HOWTO.txt
Documentation/kernel-parameters.txt
Documentation/scheduler/sched-design-CFS.txt
Documentation/scsi/scsi_fc_transport.txt
Documentation/x86/00-INDEX [new file with mode: 0644]
Documentation/x86/boot.txt [moved from Documentation/x86/i386/boot.txt with 99% similarity]
Documentation/x86/mtrr.txt [moved from Documentation/mtrr.txt with 99% similarity]
Documentation/x86/pat.txt
Documentation/x86/usb-legacy-support.txt [moved from Documentation/x86/i386/usb-legacy-support.txt with 100% similarity]
Documentation/x86/x86_64/boot-options.txt
Documentation/x86/zero-page.txt [moved from Documentation/x86/i386/zero-page.txt with 100% similarity]
MAINTAINERS
Makefile
arch/alpha/kernel/smp.c
arch/arm/kernel/smp.c
arch/cris/arch-v32/kernel/smp.c
arch/ia64/kernel/smpboot.c
arch/m32r/kernel/smpboot.c
arch/mips/kernel/smp.c
arch/powerpc/kernel/smp.c
arch/s390/kernel/smp.c
arch/sh/kernel/smp.c
arch/sparc/kernel/sun4d_smp.c
arch/sparc/kernel/sun4m_smp.c
arch/um/kernel/smp.c
arch/x86/Kconfig
arch/x86/Kconfig.cpu
arch/x86/boot/compressed/head_32.S
arch/x86/boot/compressed/misc.c
arch/x86/boot/header.S
arch/x86/configs/i386_defconfig
arch/x86/configs/x86_64_defconfig
arch/x86/crypto/Makefile
arch/x86/crypto/crc32c-intel.c [new file with mode: 0644]
arch/x86/ia32/ia32_aout.c
arch/x86/ia32/ia32_signal.c
arch/x86/ia32/sys_ia32.c
arch/x86/kernel/acpi/boot.c
arch/x86/kernel/alternative.c
arch/x86/kernel/aperture_64.c
arch/x86/kernel/apm_32.c
arch/x86/kernel/asm-offsets_64.c
arch/x86/kernel/bios_uv.c
arch/x86/kernel/cpu/common_64.c
arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
arch/x86/kernel/cpu/intel.c
arch/x86/kernel/cpu/mtrr/generic.c
arch/x86/kernel/cpu/mtrr/if.c
arch/x86/kernel/cpu/mtrr/main.c
arch/x86/kernel/cpu/perfctr-watchdog.c
arch/x86/kernel/cpuid.c
arch/x86/kernel/crash_dump_64.c
arch/x86/kernel/ds.c
arch/x86/kernel/efi.c
arch/x86/kernel/entry_64.S
arch/x86/kernel/head64.c
arch/x86/kernel/ioport.c
arch/x86/kernel/ipi.c
arch/x86/kernel/irq_32.c
arch/x86/kernel/irq_64.c
arch/x86/kernel/kvm.c
arch/x86/kernel/ldt.c
arch/x86/kernel/nmi.c
arch/x86/kernel/olpc.c
arch/x86/kernel/paravirt.c
arch/x86/kernel/paravirt_patch_32.c
arch/x86/kernel/pci-dma.c
arch/x86/kernel/pci-gart_64.c
arch/x86/kernel/pcspeaker.c
arch/x86/kernel/process.c
arch/x86/kernel/process_32.c
arch/x86/kernel/process_64.c
arch/x86/kernel/ptrace.c
arch/x86/kernel/reboot.c
arch/x86/kernel/setup.c
arch/x86/kernel/setup_percpu.c
arch/x86/kernel/sigframe.h
arch/x86/kernel/signal_32.c
arch/x86/kernel/signal_64.c
arch/x86/kernel/smpboot.c
arch/x86/kernel/sys_i386_32.c
arch/x86/kernel/sys_x86_64.c
arch/x86/kernel/syscall_64.c
arch/x86/kernel/time_32.c
arch/x86/kernel/tls.c
arch/x86/kernel/traps_64.c
arch/x86/kernel/tsc.c
arch/x86/kernel/visws_quirks.c
arch/x86/kernel/vm86_32.c
arch/x86/kernel/vmi_32.c
arch/x86/lib/msr-on-cpu.c
arch/x86/lib/string_32.c
arch/x86/lib/strstr_32.c
arch/x86/mach-default/setup.c
arch/x86/mach-voyager/voyager_smp.c
arch/x86/mm/discontig_32.c
arch/x86/mm/dump_pagetables.c
arch/x86/mm/fault.c
arch/x86/mm/init_32.c
arch/x86/mm/init_64.c
arch/x86/mm/ioremap.c
arch/x86/mm/numa_64.c
arch/x86/mm/pageattr.c
arch/x86/mm/pgtable.c
arch/x86/mm/pgtable_32.c
arch/x86/oprofile/op_model_p4.c
arch/x86/pci/amd_bus.c
arch/x86/pci/irq.c
arch/x86/power/hibernate_asm_32.S
arch/x86/xen/enlighten.c
block/Makefile
block/as-iosched.c
block/blk-barrier.c
block/blk-core.c
block/blk-exec.c
block/blk-integrity.c
block/blk-map.c
block/blk-merge.c
block/blk-settings.c
block/blk-softirq.c [new file with mode: 0644]
block/blk-sysfs.c
block/blk-tag.c
block/blk-timeout.c [new file with mode: 0644]
block/blk.h
block/blktrace.c
block/bsg.c
block/cfq-iosched.c
block/cmd-filter.c
block/compat_ioctl.c
block/deadline-iosched.c
block/elevator.c
block/genhd.c
block/ioctl.c
block/scsi_ioctl.c
crypto/Kconfig
crypto/Makefile
crypto/algapi.c
crypto/algboss.c [moved from crypto/cryptomgr.c with 69% similarity]
crypto/ansi_cprng.c [new file with mode: 0644]
crypto/api.c
crypto/blkcipher.c
crypto/chainiv.c
crypto/eseqiv.c
crypto/fips.c [new file with mode: 0644]
crypto/internal.h
crypto/krng.c [new file with mode: 0644]
crypto/proc.c
crypto/rng.c [new file with mode: 0644]
crypto/seqiv.c
crypto/tcrypt.c
crypto/tcrypt.h
crypto/testmgr.c [new file with mode: 0644]
crypto/testmgr.h [new file with mode: 0644]
drivers/ata/Kconfig
drivers/ata/ahci.c
drivers/ata/ata_piix.c
drivers/ata/libata-core.c
drivers/ata/libata-eh.c
drivers/ata/libata-scsi.c
drivers/ata/libata.h
drivers/ata/pata_bf54x.c
drivers/ata/pata_sil680.c
drivers/ata/sata_fsl.c
drivers/ata/sata_inic162x.c
drivers/ata/sata_mv.c
drivers/ata/sata_nv.c
drivers/ata/sata_promise.c
drivers/ata/sata_qstor.c
drivers/ata/sata_sil.c
drivers/ata/sata_sil24.c
drivers/ata/sata_sis.c
drivers/ata/sata_svw.c
drivers/ata/sata_uli.c
drivers/ata/sata_via.c
drivers/ata/sata_vsc.c
drivers/base/base.h
drivers/base/class.c
drivers/base/core.c
drivers/block/aoe/aoeblk.c
drivers/block/aoe/aoecmd.c
drivers/block/aoe/aoedev.c
drivers/block/cciss.c
drivers/block/cciss_scsi.c
drivers/block/cciss_scsi.h
drivers/block/cpqarray.c
drivers/block/floppy.c
drivers/block/nbd.c
drivers/block/pktcdvd.c
drivers/block/ps3disk.c
drivers/block/virtio_blk.c
drivers/block/xen-blkfront.c
drivers/cdrom/cdrom.c
drivers/cdrom/gdrom.c
drivers/char/random.c
drivers/char/tpm/Kconfig
drivers/hwmon/abituguru3.c
drivers/hwmon/it87.c
drivers/ide/ide-cd.c
drivers/ide/ide-disk.c
drivers/ide/ide-probe.c
drivers/infiniband/core/cm.c
drivers/infiniband/core/mad.c
drivers/infiniband/hw/amso1100/c2_provider.c
drivers/infiniband/hw/cxgb3/iwch_provider.c
drivers/infiniband/hw/ehca/ehca_classes.h
drivers/infiniband/hw/ehca/ehca_cq.c
drivers/infiniband/hw/ehca/ehca_iverbs.h
drivers/infiniband/hw/ehca/ehca_qp.c
drivers/infiniband/hw/ehca/ehca_reqs.c
drivers/infiniband/hw/ipath/ipath_rc.c
drivers/infiniband/hw/ipath/ipath_ruc.c
drivers/infiniband/hw/ipath/ipath_verbs.c
drivers/infiniband/hw/mlx4/qp.c
drivers/infiniband/hw/mthca/mthca_catas.c
drivers/infiniband/hw/mthca/mthca_eq.c
drivers/infiniband/hw/mthca/mthca_main.c
drivers/infiniband/hw/nes/nes.c
drivers/infiniband/hw/nes/nes.h
drivers/infiniband/hw/nes/nes_cm.c
drivers/infiniband/hw/nes/nes_hw.c
drivers/infiniband/hw/nes/nes_hw.h
drivers/infiniband/hw/nes/nes_nic.c
drivers/infiniband/hw/nes/nes_verbs.c
drivers/infiniband/ulp/ipoib/ipoib.h
drivers/infiniband/ulp/ipoib/ipoib_cm.c
drivers/infiniband/ulp/ipoib/ipoib_ib.c
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/infiniband/ulp/ipoib/ipoib_multicast.c
drivers/md/dm-crypt.c
drivers/md/dm-exception-store.c
drivers/md/dm-ioctl.c
drivers/md/dm-mpath.c
drivers/md/dm-mpath.h
drivers/md/dm-raid1.c
drivers/md/dm-stripe.c
drivers/md/dm-table.c
drivers/md/dm.c
drivers/md/dm.h
drivers/md/linear.c
drivers/md/md.c
drivers/md/multipath.c
drivers/md/raid0.c
drivers/md/raid1.c
drivers/md/raid10.c
drivers/md/raid5.c
drivers/memstick/core/mspro_block.c
drivers/misc/eeepc-laptop.c
drivers/mmc/card/block.c
drivers/mtd/ftl.c
drivers/mtd/mtd_blkdevs.c
drivers/pnp/Makefile
drivers/pnp/pnpacpi/core.c
drivers/pnp/pnpbios/core.c
drivers/s390/block/dasd_proc.c
drivers/s390/block/dcssblk.c
drivers/s390/scsi/zfcp_aux.c
drivers/s390/scsi/zfcp_ccw.c
drivers/s390/scsi/zfcp_dbf.c
drivers/s390/scsi/zfcp_dbf.h
drivers/s390/scsi/zfcp_def.h
drivers/s390/scsi/zfcp_erp.c
drivers/s390/scsi/zfcp_ext.h
drivers/s390/scsi/zfcp_fc.c
drivers/s390/scsi/zfcp_fsf.c
drivers/s390/scsi/zfcp_fsf.h
drivers/s390/scsi/zfcp_qdio.c
drivers/s390/scsi/zfcp_scsi.c
drivers/s390/scsi/zfcp_sysfs.c
drivers/scsi/Kconfig
drivers/scsi/aacraid/aachba.c
drivers/scsi/device_handler/scsi_dh_emc.c
drivers/scsi/device_handler/scsi_dh_hp_sw.c
drivers/scsi/device_handler/scsi_dh_rdac.c
drivers/scsi/gdth.c
drivers/scsi/gdth.h
drivers/scsi/gdth_proc.c
drivers/scsi/gdth_proc.h
drivers/scsi/hosts.c
drivers/scsi/ibmvscsi/ibmvscsi.c
drivers/scsi/ide-scsi.c
drivers/scsi/ipr.c
drivers/scsi/ips.c
drivers/scsi/libiscsi.c
drivers/scsi/libsas/sas_ata.c
drivers/scsi/libsas/sas_internal.h
drivers/scsi/libsas/sas_scsi_host.c
drivers/scsi/megaraid/megaraid_sas.c
drivers/scsi/ncr53c8xx.c
drivers/scsi/qla1280.c
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_fw.h
drivers/scsi/qla2xxx/qla_gbl.h
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_inline.h
drivers/scsi/qla2xxx/qla_iocb.c
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qla2xxx/qla_sup.c
drivers/scsi/qla2xxx/qla_version.h
drivers/scsi/qla4xxx/ql4_os.c
drivers/scsi/scsi.c
drivers/scsi/scsi_error.c
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_netlink.c
drivers/scsi/scsi_priv.h
drivers/scsi/scsi_proc.c
drivers/scsi/scsi_scan.c
drivers/scsi/scsi_sysfs.c
drivers/scsi/scsi_tgt_lib.c
drivers/scsi/scsi_transport_fc.c
drivers/scsi/scsi_transport_iscsi.c
drivers/scsi/sd.c
drivers/scsi/sg.c
drivers/scsi/sr.c
drivers/scsi/sym53c8xx_2/sym_glue.c
drivers/scsi/tmscsim.c
fs/bio-integrity.c
fs/bio.c
fs/block_dev.c
fs/dlm/config.c
fs/dlm/dlm_internal.h
fs/dlm/lockspace.c
fs/dlm/lockspace.h
fs/dlm/user.c
fs/dlm/user.h
fs/fat/fatent.c
fs/gfs2/glock.c
fs/gfs2/glock.h
fs/gfs2/incore.h
fs/gfs2/inode.c
fs/gfs2/inode.h
fs/gfs2/locking/dlm/mount.c
fs/gfs2/log.c
fs/gfs2/mount.c
fs/gfs2/ops_address.c
fs/gfs2/ops_file.c
fs/gfs2/ops_fstype.c
fs/gfs2/ops_inode.c
fs/gfs2/ops_super.c
fs/gfs2/super.c
fs/gfs2/super.h
fs/gfs2/sys.c
fs/partitions/check.c
fs/partitions/check.h
fs/splice.c
fs/xfs/linux-2.6/xfs_buf.c
fs/xfs/linux-2.6/xfs_buf.h
fs/xfs/xfs_log.c
include/asm-x86/a.out-core.h
include/asm-x86/a.out.h
include/asm-x86/acpi.h
include/asm-x86/agp.h
include/asm-x86/alternative.h
include/asm-x86/amd_iommu.h
include/asm-x86/amd_iommu_types.h
include/asm-x86/apic.h
include/asm-x86/apicdef.h
include/asm-x86/arch_hooks.h
include/asm-x86/asm.h
include/asm-x86/atomic_32.h
include/asm-x86/atomic_64.h
include/asm-x86/auxvec.h
include/asm-x86/bios_ebda.h
include/asm-x86/bitops.h
include/asm-x86/boot.h
include/asm-x86/bootparam.h
include/asm-x86/bug.h
include/asm-x86/bugs.h
include/asm-x86/byteorder.h
include/asm-x86/cache.h
include/asm-x86/cacheflush.h
include/asm-x86/calgary.h
include/asm-x86/checksum_32.h
include/asm-x86/checksum_64.h
include/asm-x86/cmpxchg_32.h
include/asm-x86/cmpxchg_64.h
include/asm-x86/compat.h
include/asm-x86/cpu.h
include/asm-x86/cpufeature.h
include/asm-x86/current.h
include/asm-x86/debugreg.h
include/asm-x86/delay.h
include/asm-x86/desc.h
include/asm-x86/desc_defs.h
include/asm-x86/device.h
include/asm-x86/div64.h
include/asm-x86/dma-mapping.h
include/asm-x86/dma.h
include/asm-x86/dmi.h
include/asm-x86/ds.h
include/asm-x86/dwarf2.h
include/asm-x86/e820.h
include/asm-x86/edac.h
include/asm-x86/efi.h
include/asm-x86/elf.h
include/asm-x86/emergency-restart.h
include/asm-x86/fb.h
include/asm-x86/fixmap.h
include/asm-x86/fixmap_32.h
include/asm-x86/fixmap_64.h
include/asm-x86/floppy.h
include/asm-x86/ftrace.h
include/asm-x86/futex.h
include/asm-x86/gart.h
include/asm-x86/genapic_32.h
include/asm-x86/genapic_64.h
include/asm-x86/geode.h
include/asm-x86/gpio.h
include/asm-x86/hardirq_32.h
include/asm-x86/hardirq_64.h
include/asm-x86/highmem.h
include/asm-x86/hpet.h
include/asm-x86/hugetlb.h
include/asm-x86/hw_irq.h
include/asm-x86/hypertransport.h
include/asm-x86/i387.h
include/asm-x86/i8253.h
include/asm-x86/i8259.h
include/asm-x86/ia32.h
include/asm-x86/ia32_unistd.h
include/asm-x86/idle.h
include/asm-x86/intel_arch_perfmon.h
include/asm-x86/io.h
include/asm-x86/io_32.h
include/asm-x86/io_64.h
include/asm-x86/io_apic.h
include/asm-x86/ioctls.h
include/asm-x86/iommu.h
include/asm-x86/ipcbuf.h
include/asm-x86/ipi.h
include/asm-x86/irq.h
include/asm-x86/irq_regs_32.h
include/asm-x86/irq_vectors.h
include/asm-x86/ist.h
include/asm-x86/k8.h
include/asm-x86/kdebug.h
include/asm-x86/kexec.h
include/asm-x86/kgdb.h
include/asm-x86/kmap_types.h
include/asm-x86/kprobes.h
include/asm-x86/kvm.h
include/asm-x86/kvm_host.h
include/asm-x86/kvm_para.h
include/asm-x86/kvm_x86_emulate.h
include/asm-x86/ldt.h
include/asm-x86/lguest.h
include/asm-x86/lguest_hcall.h
include/asm-x86/linkage.h
include/asm-x86/local.h
include/asm-x86/mach-bigsmp/mach_apic.h
include/asm-x86/mach-bigsmp/mach_apicdef.h
include/asm-x86/mach-bigsmp/mach_ipi.h
include/asm-x86/mach-default/apm.h
include/asm-x86/mach-default/mach_apic.h
include/asm-x86/mach-default/mach_apicdef.h
include/asm-x86/mach-default/mach_ipi.h
include/asm-x86/mach-default/mach_mpparse.h
include/asm-x86/mach-default/mach_mpspec.h
include/asm-x86/mach-default/mach_timer.h
include/asm-x86/mach-default/mach_traps.h
include/asm-x86/mach-default/mach_wakecpu.h
include/asm-x86/mach-es7000/mach_apic.h
include/asm-x86/mach-es7000/mach_apicdef.h
include/asm-x86/mach-es7000/mach_ipi.h
include/asm-x86/mach-es7000/mach_mpparse.h
include/asm-x86/mach-es7000/mach_wakecpu.h
include/asm-x86/mach-generic/gpio.h
include/asm-x86/mach-generic/irq_vectors_limits.h
include/asm-x86/mach-generic/mach_apic.h
include/asm-x86/mach-generic/mach_apicdef.h
include/asm-x86/mach-generic/mach_ipi.h
include/asm-x86/mach-generic/mach_mpparse.h
include/asm-x86/mach-generic/mach_mpspec.h
include/asm-x86/mach-numaq/mach_apic.h
include/asm-x86/mach-numaq/mach_apicdef.h
include/asm-x86/mach-numaq/mach_ipi.h
include/asm-x86/mach-numaq/mach_mpparse.h
include/asm-x86/mach-numaq/mach_wakecpu.h
include/asm-x86/mach-rdc321x/gpio.h
include/asm-x86/mach-summit/irq_vectors_limits.h
include/asm-x86/mach-summit/mach_apic.h
include/asm-x86/mach-summit/mach_apicdef.h
include/asm-x86/mach-summit/mach_ipi.h
include/asm-x86/mach-summit/mach_mpparse.h
include/asm-x86/math_emu.h
include/asm-x86/mc146818rtc.h
include/asm-x86/mca.h
include/asm-x86/mca_dma.h
include/asm-x86/mce.h
include/asm-x86/mman.h
include/asm-x86/mmconfig.h
include/asm-x86/mmu.h
include/asm-x86/mmu_context.h
include/asm-x86/mmu_context_32.h
include/asm-x86/mmu_context_64.h
include/asm-x86/mmx.h
include/asm-x86/mmzone_32.h
include/asm-x86/mmzone_64.h
include/asm-x86/module.h
include/asm-x86/mpspec.h
include/asm-x86/mpspec_def.h
include/asm-x86/msgbuf.h
include/asm-x86/msidef.h
include/asm-x86/msr-index.h
include/asm-x86/msr.h
include/asm-x86/mtrr.h
include/asm-x86/mutex_32.h
include/asm-x86/mutex_64.h
include/asm-x86/nmi.h
include/asm-x86/nops.h
include/asm-x86/numa_32.h
include/asm-x86/numa_64.h
include/asm-x86/numaq.h
include/asm-x86/olpc.h
include/asm-x86/page.h
include/asm-x86/page_32.h
include/asm-x86/page_64.h
include/asm-x86/param.h
include/asm-x86/paravirt.h
include/asm-x86/parport.h
include/asm-x86/pat.h
include/asm-x86/pci-direct.h
include/asm-x86/pci.h
include/asm-x86/pci_32.h
include/asm-x86/pci_64.h
include/asm-x86/pda.h
include/asm-x86/percpu.h
include/asm-x86/pgalloc.h
include/asm-x86/pgtable-2level-defs.h
include/asm-x86/pgtable-2level.h
include/asm-x86/pgtable-3level-defs.h
include/asm-x86/pgtable-3level.h
include/asm-x86/pgtable.h
include/asm-x86/pgtable_32.h
include/asm-x86/pgtable_64.h
include/asm-x86/posix_types_32.h
include/asm-x86/posix_types_64.h
include/asm-x86/prctl.h
include/asm-x86/processor-flags.h
include/asm-x86/processor.h
include/asm-x86/proto.h
include/asm-x86/ptrace-abi.h
include/asm-x86/ptrace.h
include/asm-x86/pvclock-abi.h
include/asm-x86/pvclock.h
include/asm-x86/reboot.h
include/asm-x86/reboot_fixups.h
include/asm-x86/required-features.h
include/asm-x86/resume-trace.h
include/asm-x86/rio.h
include/asm-x86/rwlock.h
include/asm-x86/rwsem.h
include/asm-x86/scatterlist.h
include/asm-x86/seccomp_32.h
include/asm-x86/seccomp_64.h
include/asm-x86/segment.h
include/asm-x86/sembuf.h
include/asm-x86/serial.h
include/asm-x86/setup.h
include/asm-x86/shmbuf.h
include/asm-x86/shmparam.h
include/asm-x86/sigcontext.h
include/asm-x86/sigcontext32.h
include/asm-x86/siginfo.h
include/asm-x86/signal.h
include/asm-x86/smp.h
include/asm-x86/socket.h
include/asm-x86/sockios.h
include/asm-x86/sparsemem.h
include/asm-x86/spinlock.h
include/asm-x86/spinlock_types.h
include/asm-x86/srat.h
include/asm-x86/stacktrace.h
include/asm-x86/stat.h
include/asm-x86/statfs.h
include/asm-x86/string_32.h
include/asm-x86/string_64.h
include/asm-x86/suspend_32.h
include/asm-x86/suspend_64.h
include/asm-x86/swiotlb.h
include/asm-x86/sync_bitops.h
include/asm-x86/syscall.h [new file with mode: 0644]
include/asm-x86/syscalls.h [new file with mode: 0644]
include/asm-x86/system.h
include/asm-x86/system_64.h
include/asm-x86/tce.h
include/asm-x86/termbits.h
include/asm-x86/termios.h
include/asm-x86/therm_throt.h
include/asm-x86/thread_info.h
include/asm-x86/time.h
include/asm-x86/timer.h
include/asm-x86/timex.h
include/asm-x86/tlb.h
include/asm-x86/tlbflush.h
include/asm-x86/topology.h
include/asm-x86/trampoline.h
include/asm-x86/traps.h
include/asm-x86/tsc.h
include/asm-x86/types.h
include/asm-x86/uaccess.h
include/asm-x86/uaccess_32.h
include/asm-x86/uaccess_64.h
include/asm-x86/ucontext.h
include/asm-x86/unaligned.h
include/asm-x86/unistd_32.h
include/asm-x86/unistd_64.h
include/asm-x86/unwind.h
include/asm-x86/user32.h
include/asm-x86/user_32.h
include/asm-x86/user_64.h
include/asm-x86/uv/bios.h
include/asm-x86/uv/uv_bau.h
include/asm-x86/uv/uv_hub.h
include/asm-x86/uv/uv_mmrs.h
include/asm-x86/vdso.h
include/asm-x86/vga.h
include/asm-x86/vgtod.h
include/asm-x86/visws/cobalt.h
include/asm-x86/visws/lithium.h
include/asm-x86/visws/piix4.h
include/asm-x86/vm86.h
include/asm-x86/vmi_time.h
include/asm-x86/vsyscall.h
include/asm-x86/xen/events.h
include/asm-x86/xen/grant_table.h
include/asm-x86/xen/hypercall.h
include/asm-x86/xen/hypervisor.h
include/asm-x86/xen/interface.h
include/asm-x86/xen/interface_32.h
include/asm-x86/xen/interface_64.h
include/asm-x86/xen/page.h
include/crypto/internal/rng.h [new file with mode: 0644]
include/crypto/internal/skcipher.h
include/crypto/rng.h [new file with mode: 0644]
include/linux/Kbuild
include/linux/ata.h
include/linux/bio.h
include/linux/blkdev.h
include/linux/blktrace_api.h
include/linux/completion.h
include/linux/cpu.h
include/linux/crypto.h
include/linux/device-mapper.h
include/linux/device.h
include/linux/dlm.h
include/linux/dlm_device.h
include/linux/elevator.h
include/linux/fd.h
include/linux/fs.h
include/linux/genhd.h
include/linux/gfs2_ondisk.h
include/linux/klist.h
include/linux/libata.h
include/linux/major.h
include/linux/mtd/blktrans.h
include/linux/notifier.h
include/linux/proportions.h
include/linux/sched.h
include/linux/security.h
include/linux/string_helpers.h [new file with mode: 0644]
include/scsi/scsi_cmnd.h
include/scsi/scsi_device.h
include/scsi/scsi_host.h
include/scsi/scsi_netlink.h
include/scsi/scsi_transport.h
include/scsi/scsi_transport_fc.h
init/do_mounts.c
kernel/cpu.c
kernel/cpuset.c
kernel/sched.c
kernel/sched_fair.c
kernel/sched_features.h
kernel/sched_idletask.c
kernel/sched_rt.c
kernel/user.c
lib/Kconfig.debug
lib/Makefile
lib/klist.c
lib/string_helpers.c [new file with mode: 0644]
mm/bounce.c
mm/slob.c
scripts/Makefile
scripts/selinux/Makefile [new file with mode: 0644]
scripts/selinux/README [new file with mode: 0644]
scripts/selinux/install_policy.sh [new file with mode: 0644]
scripts/selinux/mdp/.gitignore [new file with mode: 0644]
scripts/selinux/mdp/Makefile [new file with mode: 0644]
scripts/selinux/mdp/dbus_contexts [new file with mode: 0644]
scripts/selinux/mdp/mdp.c [new file with mode: 0644]
security/Kconfig
security/Makefile
security/commoncap.c
security/inode.c
security/security.c
security/selinux/Kconfig
security/selinux/avc.c
security/selinux/hooks.c
security/selinux/include/avc.h
security/selinux/include/security.h
security/selinux/ss/avtab.c
security/selinux/ss/conditional.c
security/selinux/ss/conditional.h
security/selinux/ss/ebitmap.c
security/selinux/ss/hashtab.c
security/selinux/ss/mls.c
security/selinux/ss/policydb.c
security/selinux/ss/policydb.h
security/selinux/ss/services.c
security/selinux/ss/sidtab.c
security/smack/smack.h
security/smack/smack_access.c
security/smack/smackfs.c

index 5b5aba404aacb69160f0d88301be0a76aea78682..73060819ed99c6889c716cf922e1997f37f4a0b0 100644 (file)
@@ -251,8 +251,6 @@ mono.txt
        - how to execute Mono-based .NET binaries with the help of BINFMT_MISC.
 moxa-smartio
        - file with info on installing/using Moxa multiport serial driver.
-mtrr.txt
-       - how to use PPro Memory Type Range Registers to increase performance.
 mutex-design.txt
        - info on the generic mutex subsystem.
 namespaces/
index d8b63d164e41193927af2c7fb41dcb0893f57878..b8e86460046e7ee3dba003c12de57ae2d6f7fb36 100644 (file)
@@ -337,7 +337,7 @@ With scatterlists, you use the resulting mapping like this:
        int i, count = dma_map_sg(dev, sglist, nents, direction);
        struct scatterlist *sg;
 
-       for (i = 0, sg = sglist; i < count; i++, sg++) {
+       for_each_sg(sglist, sg, count, i) {
                hw_address[i] = sg_dma_address(sg);
                hw_len[i] = sg_dma_len(sg);
        }
index b7b1482f6e04ebda24e665d0734fb4786bfc197a..9d0058e788e53430f1b33bf8ff40d3ff4f6f67b1 100644 (file)
@@ -283,6 +283,7 @@ X!Earch/x86/kernel/mca_32.c
   <chapter id="security">
      <title>Security Framework</title>
 !Isecurity/security.c
+!Esecurity/inode.c
   </chapter>
 
   <chapter id="audit">
@@ -364,6 +365,10 @@ X!Edrivers/pnp/system.c
 !Eblock/blk-barrier.c
 !Eblock/blk-tag.c
 !Iblock/blk-tag.c
+!Eblock/blk-integrity.c
+!Iblock/blktrace.c
+!Iblock/genhd.c
+!Eblock/genhd.c
   </chapter>
 
   <chapter id="chrdev">
diff --git a/Documentation/SELinux.txt b/Documentation/SELinux.txt
new file mode 100644 (file)
index 0000000..07eae00
--- /dev/null
@@ -0,0 +1,27 @@
+If you want to use SELinux, chances are you will want
+to use the distro-provided policies, or install the
+latest reference policy release from
+       http://oss.tresys.com/projects/refpolicy
+
+However, if you want to install a dummy policy for
+testing, you can do using 'mdp' provided under
+scripts/selinux.  Note that this requires the selinux
+userspace to be installed - in particular you will
+need checkpolicy to compile a kernel, and setfiles and
+fixfiles to label the filesystem.
+
+       1. Compile the kernel with selinux enabled.
+       2. Type 'make' to compile mdp.
+       3. Make sure that you are not running with
+          SELinux enabled and a real policy.  If
+          you are, reboot with selinux disabled
+          before continuing.
+       4. Run install_policy.sh:
+               cd scripts/selinux
+               sh install_policy.sh
+
+Step 4 will create a new dummy policy valid for your
+kernel, with a single selinux user, role, and type.
+It will compile the policy, will set your SELINUXTYPE to
+dummy in /etc/selinux/config, install the compiled policy
+as 'dummy', and relabel your filesystem.
index c23cab13c3d1403a1a2f599a6b26b461296d2234..72576769e0f4976fead6933727edc02f2704092e 100644 (file)
@@ -30,12 +30,18 @@ write_expire        (in ms)
 Similar to read_expire mentioned above, but for writes.
 
 
-fifo_batch
+fifo_batch     (number of requests)
 ----------
 
-When a read request expires its deadline, we must move some requests from
-the sorted io scheduler list to the block device dispatch queue. fifo_batch
-controls how many requests we move.
+Requests are grouped into ``batches'' of a particular data direction (read or
+write) which are serviced in increasing sector order.  To limit extra seeking,
+deadline expiries are only checked between batches.  fifo_batch controls the
+maximum number of requests per batch.
+
+This parameter tunes the balance between per-request latency and aggregate
+throughput.  When low latency is the primary concern, smaller is better (where
+a value of 1 yields first-come first-served behaviour).  Increasing fifo_batch
+generally improves throughput, at the cost of latency variation.
 
 
 writes_starved (number of dispatches)
index 91c0dcc6fa5ca92d29124951e83f7e8c8b4e3b32..2c558cd6c1ef605f11dfe2a1dff1be292946d57e 100644 (file)
@@ -145,8 +145,7 @@ useful for reading photocds.
 
 To play an audio CD, you should first unmount and remove any data
 CDROM.  Any of the CDROM player programs should then work (workman,
-workbone, cdplayer, etc.).  Lacking anything else, you could use the
-cdtester program in Documentation/cdrom/sbpcd.
+workbone, cdplayer, etc.).
 
 On a few drives, you can read digital audio directly using a program
 such as cdda2wav.  The only types of drive which I've heard support
index ffdb5323df378b84963e4f91cd1470ff17865b6d..3d0b915035b9f28fbcff7d83a91ef016d4d7b2ad 100644 (file)
@@ -35,11 +35,9 @@ Mailing List
 ------------
 There is a CPU frequency changing CVS commit and general list where
 you can report bugs, problems or submit patches. To post a message,
-send an email to cpufreq@lists.linux.org.uk, to subscribe go to
-http://lists.linux.org.uk/mailman/listinfo/cpufreq. Previous post to the
-mailing list are available to subscribers at
-http://lists.linux.org.uk/mailman/private/cpufreq/.
-
+send an email to cpufreq@vger.kernel.org, to subscribe go to
+http://vger.kernel.org/vger-lists.html#cpufreq and follow the
+instructions there.
 
 Links
 -----
@@ -50,7 +48,7 @@ how to access the CVS repository:
 * http://cvs.arm.linux.org.uk/
 
 the CPUFreq Mailing list:
-* http://lists.linux.org.uk/mailman/listinfo/cpufreq
+* http://vger.kernel.org/vger-lists.html#cpufreq
 
 Clock and voltage scaling for the SA-1100:
 * http://www.lartmaker.nl/projects/scaling
index 2126de34c71161a3e6f22ddbfe082725b01cfc24..1cbf671822e23d063c648984c145149792978c62 100644 (file)
@@ -14,14 +14,14 @@ Description
 
 This driver implements support for the Analog Devices ADT7473 chip family.
 
-The LM85 uses the 2-wire interface compatible with the SMBUS 2.0
+The ADT7473 uses the 2-wire interface compatible with the SMBUS 2.0
 specification. Using an analog to digital converter it measures three (3)
-temperatures and two (2) voltages. It has three (3) 16-bit counters for
+temperatures and two (2) voltages. It has four (4) 16-bit counters for
 measuring fan speed. There are three (3) PWM outputs that can be used
 to control fan speed.
 
 A sophisticated control system for the PWM outputs is designed into the
-LM85 that allows fan speed to be adjusted automatically based on any of the
+ADT7473 that allows fan speed to be adjusted automatically based on any of the
 three temperature sensors. Each PWM output is individually adjustable and
 programmable. Once configured, the ADT7473 will adjust the PWM outputs in
 response to the measured temperatures without further host intervention.
@@ -46,14 +46,6 @@ from the raw value to get the temperature value.
 The Analog Devices datasheet is very detailed and describes a procedure for
 determining an optimal configuration for the automatic PWM control.
 
-Hardware Configurations
------------------------
-
-The ADT7473 chips have an optional SMBALERT output that can be used to
-signal the chipset in case a limit is exceeded or the temperature sensors
-fail. Individual sensor interrupts can be masked so they won't trigger
-SMBALERT. The SMBALERT output if configured replaces the PWM2 function.
-
 Configuration Notes
 -------------------
 
@@ -61,8 +53,8 @@ Besides standard interfaces driver adds the following:
 
 * PWM Control
 
-* pwm#_auto_point1_pwm and pwm#_auto_point1_temp and
-* pwm#_auto_point2_pwm and pwm#_auto_point2_temp -
+* pwm#_auto_point1_pwm and temp#_auto_point1_temp and
+* pwm#_auto_point2_pwm and temp#_auto_point2_temp -
 
 point1: Set the pwm speed at a lower temperature bound.
 point2: Set the pwm speed at a higher temperature bound.
index 2d845730d4e0e81c65ff5ceb5299a79724daf62f..6dbfd5efd991de9f6a69eaa831d1a45634ba5979 100644 (file)
@@ -329,6 +329,10 @@ power[1-*]_average         Average power use
                                Unit: microWatt
                                RO
 
+power[1-*]_average_interval    Power use averaging interval
+                               Unit: milliseconds
+                               RW
+
 power[1-*]_average_highest     Historical average maximum power use
                                Unit: microWatt
                                RO
@@ -353,6 +357,14 @@ power[1-*]_reset_history   Reset input_highest, input_lowest,
                                average_highest and average_lowest.
                                WO
 
+**********
+* Energy *
+**********
+
+energy[1-*]_input              Cumulative energy use
+                               Unit: microJoule
+                               RO
+
 **********
 * Alarms *
 **********
index 0bd32748a467be8e7436f4ff3ec684b784755663..c6841eee9598ddd82932db9e4e4a451f9f33ad9d 100644 (file)
@@ -168,10 +168,10 @@ if ($#ARGV < 0) {
 mkdir $ARGV[0],0777;
 $state = 0;
 while (<STDIN>) {
-    if (/^\.TH \"[^\"]*\" 4 \"([^\"]*)\"/) {
+    if (/^\.TH \"[^\"]*\" 9 \"([^\"]*)\"/) {
        if ($state == 1) { close OUT }
        $state = 1;
-       $fn = "$ARGV[0]/$1.4";
+       $fn = "$ARGV[0]/$1.9";
        print STDERR "Creating $fn\n";
        open OUT, ">$fn" or die "can't open $fn: $!\n";
        print OUT $_;
index 1150444a21ab64140f13e706797f16664e28244f..329dcabe4c5eae0382a2902839d0f91d69d442d7 100644 (file)
@@ -463,12 +463,6 @@ and is between 256 and 4096 characters. It is defined in the file
                        Range: 0 - 8192
                        Default: 64
 
-       disable_8254_timer
-       enable_8254_timer
-                       [IA32/X86_64] Disable/Enable interrupt 0 timer routing
-                       over the 8254 in addition to over the IO-APIC. The
-                       kernel tries to set a sensible default.
-
        hpet=           [X86-32,HPET] option to control HPET usage
                        Format: { enable (default) | disable | force }
                        disable: disable HPET and use PIT instead
@@ -1882,6 +1876,12 @@ and is between 256 and 4096 characters. It is defined in the file
        shapers=        [NET]
                        Maximal number of shapers.
 
+       show_msr=       [x86] show boot-time MSR settings
+                       Format: { <integer> }
+                       Show boot-time (BIOS-initialized) MSR settings.
+                       The parameter means the number of CPUs to show,
+                       for example 1 means boot CPU only.
+
        sim710=         [SCSI,HW]
                        See header of drivers/scsi/sim710.c.
 
index 88bcb87673354302737be5bbaac5b8c049941d86..9d8eb553884c130cc16f5c50eaeb4e6ca73dbab6 100644 (file)
+                      =============
+                      CFS Scheduler
+                      =============
 
-This is the CFS scheduler.
-
-80% of CFS's design can be summed up in a single sentence: CFS basically
-models an "ideal, precise multi-tasking CPU" on real hardware.
-
-"Ideal multi-tasking CPU" is a (non-existent  :-))  CPU that has 100%
-physical power and which can run each task at precise equal speed, in
-parallel, each at 1/nr_running speed. For example: if there are 2 tasks
-running then it runs each at 50% physical power - totally in parallel.
-
-On real hardware, we can run only a single task at once, so while that
-one task runs, the other tasks that are waiting for the CPU are at a
-disadvantage - the current task gets an unfair amount of CPU time. In
-CFS this fairness imbalance is expressed and tracked via the per-task
-p->wait_runtime (nanosec-unit) value. "wait_runtime" is the amount of
-time the task should now run on the CPU for it to become completely fair
-and balanced.
-
-( small detail: on 'ideal' hardware, the p->wait_runtime value would
-  always be zero - no task would ever get 'out of balance' from the
-  'ideal' share of CPU time. )
-
-CFS's task picking logic is based on this p->wait_runtime value and it
-is thus very simple: it always tries to run the task with the largest
-p->wait_runtime value. In other words, CFS tries to run the task with
-the 'gravest need' for more CPU time. So CFS always tries to split up
-CPU time between runnable tasks as close to 'ideal multitasking
-hardware' as possible.
-
-Most of the rest of CFS's design just falls out of this really simple
-concept, with a few add-on embellishments like nice levels,
-multiprocessing and various algorithm variants to recognize sleepers.
-
-In practice it works like this: the system runs a task a bit, and when
-the task schedules (or a scheduler tick happens) the task's CPU usage is
-'accounted for': the (small) time it just spent using the physical CPU
-is deducted from p->wait_runtime. [minus the 'fair share' it would have
-gotten anyway]. Once p->wait_runtime gets low enough so that another
-task becomes the 'leftmost task' of the time-ordered rbtree it maintains
-(plus a small amount of 'granularity' distance relative to the leftmost
-task so that we do not over-schedule tasks and trash the cache) then the
-new leftmost task is picked and the current task is preempted.
-
-The rq->fair_clock value tracks the 'CPU time a runnable task would have
-fairly gotten, had it been runnable during that time'. So by using
-rq->fair_clock values we can accurately timestamp and measure the
-'expected CPU time' a task should have gotten. All runnable tasks are
-sorted in the rbtree by the "rq->fair_clock - p->wait_runtime" key, and
-CFS picks the 'leftmost' task and sticks to it. As the system progresses
-forwards, newly woken tasks are put into the tree more and more to the
-right - slowly but surely giving a chance for every task to become the
-'leftmost task' and thus get on the CPU within a deterministic amount of
-time.
-
-Some implementation details:
-
- - the introduction of Scheduling Classes: an extensible hierarchy of
-   scheduler modules. These modules encapsulate scheduling policy
-   details and are handled by the scheduler core without the core
-   code assuming about them too much.
-
- - sched_fair.c implements the 'CFS desktop scheduler': it is a
-   replacement for the vanilla scheduler's SCHED_OTHER interactivity
-   code.
-
-   I'd like to give credit to Con Kolivas for the general approach here:
-   he has proven via RSDL/SD that 'fair scheduling' is possible and that
-   it results in better desktop scheduling. Kudos Con!
-
-   The CFS patch uses a completely different approach and implementation
-   from RSDL/SD. My goal was to make CFS's interactivity quality exceed
-   that of RSDL/SD, which is a high standard to meet :-) Testing
-   feedback is welcome to decide this one way or another. [ and, in any
-   case, all of SD's logic could be added via a kernel/sched_sd.c module
-   as well, if Con is interested in such an approach. ]
-
-   CFS's design is quite radical: it does not use runqueues, it uses a
-   time-ordered rbtree to build a 'timeline' of future task execution,
-   and thus has no 'array switch' artifacts (by which both the vanilla
-   scheduler and RSDL/SD are affected).
-
-   CFS uses nanosecond granularity accounting and does not rely on any
-   jiffies or other HZ detail. Thus the CFS scheduler has no notion of
-   'timeslices' and has no heuristics whatsoever. There is only one
-   central tunable (you have to switch on CONFIG_SCHED_DEBUG):
-
-         /proc/sys/kernel/sched_granularity_ns
-
-   which can be used to tune the scheduler from 'desktop' (low
-   latencies) to 'server' (good batching) workloads. It defaults to a
-   setting suitable for desktop workloads. SCHED_BATCH is handled by the
-   CFS scheduler module too.
-
-   Due to its design, the CFS scheduler is not prone to any of the
-   'attacks' that exist today against the heuristics of the stock
-   scheduler: fiftyp.c, thud.c, chew.c, ring-test.c, massive_intr.c all
-   work fine and do not impact interactivity and produce the expected
-   behavior.
-
-   the CFS scheduler has a much stronger handling of nice levels and
-   SCHED_BATCH: both types of workloads should be isolated much more
-   agressively than under the vanilla scheduler.
-
-   ( another detail: due to nanosec accounting and timeline sorting,
-     sched_yield() support is very simple under CFS, and in fact under
-     CFS sched_yield() behaves much better than under any other
-     scheduler i have tested so far. )
-
- - sched_rt.c implements SCHED_FIFO and SCHED_RR semantics, in a simpler
-   way than the vanilla scheduler does. It uses 100 runqueues (for all
-   100 RT priority levels, instead of 140 in the vanilla scheduler)
-   and it needs no expired array.
-
- - reworked/sanitized SMP load-balancing: the runqueue-walking
-   assumptions are gone from the load-balancing code now, and
-   iterators of the scheduling modules are used. The balancing code got
-   quite a bit simpler as a result.
-
-
-Group scheduler extension to CFS
-================================
-
-Normally the scheduler operates on individual tasks and strives to provide
-fair CPU time to each task. Sometimes, it may be desirable to group tasks
-and provide fair CPU time to each such task group. For example, it may
-be desirable to first provide fair CPU time to each user on the system
-and then to each task belonging to a user.
-
-CONFIG_FAIR_GROUP_SCHED strives to achieve exactly that. It lets
-SCHED_NORMAL/BATCH tasks be be grouped and divides CPU time fairly among such
-groups. At present, there are two (mutually exclusive) mechanisms to group
-tasks for CPU bandwidth control purpose:
-
-       - Based on user id (CONFIG_FAIR_USER_SCHED)
-               In this option, tasks are grouped according to their user id.
-       - Based on "cgroup" pseudo filesystem (CONFIG_FAIR_CGROUP_SCHED)
-               This options lets the administrator create arbitrary groups
-               of tasks, using the "cgroup" pseudo filesystem. See
-               Documentation/cgroups.txt for more information about this
-               filesystem.
 
-Only one of these options to group tasks can be chosen and not both.
+1.  OVERVIEW
+
+CFS stands for "Completely Fair Scheduler," and is the new "desktop" process
+scheduler implemented by Ingo Molnar and merged in Linux 2.6.23.  It is the
+replacement for the previous vanilla scheduler's SCHED_OTHER interactivity
+code.
+
+80% of CFS's design can be summed up in a single sentence: CFS basically models
+an "ideal, precise multi-tasking CPU" on real hardware.
+
+"Ideal multi-tasking CPU" is a (non-existent  :-)) CPU that has 100% physical
+power and which can run each task at precise equal speed, in parallel, each at
+1/nr_running speed.  For example: if there are 2 tasks running, then it runs
+each at 50% physical power --- i.e., actually in parallel.
+
+On real hardware, we can run only a single task at once, so we have to
+introduce the concept of "virtual runtime."  The virtual runtime of a task
+specifies when its next timeslice would start execution on the ideal
+multi-tasking CPU described above.  In practice, the virtual runtime of a task
+is its actual runtime normalized to the total number of running tasks.
+
+
+
+2.  FEW IMPLEMENTATION DETAILS
+
+In CFS the virtual runtime is expressed and tracked via the per-task
+p->se.vruntime (nanosec-unit) value.  This way, it's possible to accurately
+timestamp and measure the "expected CPU time" a task should have gotten.
+
+[ small detail: on "ideal" hardware, at any time all tasks would have the same
+  p->se.vruntime value --- i.e., tasks would execute simultaneously and no task
+  would ever get "out of balance" from the "ideal" share of CPU time.  ]
+
+CFS's task picking logic is based on this p->se.vruntime value and it is thus
+very simple: it always tries to run the task with the smallest p->se.vruntime
+value (i.e., the task which executed least so far).  CFS always tries to split
+up CPU time between runnable tasks as close to "ideal multitasking hardware" as
+possible.
+
+Most of the rest of CFS's design just falls out of this really simple concept,
+with a few add-on embellishments like nice levels, multiprocessing and various
+algorithm variants to recognize sleepers.
+
+
+
+3.  THE RBTREE
+
+CFS's design is quite radical: it does not use the old data structures for the
+runqueues, but it uses a time-ordered rbtree to build a "timeline" of future
+task execution, and thus has no "array switch" artifacts (by which both the
+previous vanilla scheduler and RSDL/SD are affected).
+
+CFS also maintains the rq->cfs.min_vruntime value, which is a monotonic
+increasing value tracking the smallest vruntime among all tasks in the
+runqueue.  The total amount of work done by the system is tracked using
+min_vruntime; that value is used to place newly activated entities on the left
+side of the tree as much as possible.
+
+The total number of running tasks in the runqueue is accounted through the
+rq->cfs.load value, which is the sum of the weights of the tasks queued on the
+runqueue.
+
+CFS maintains a time-ordered rbtree, where all runnable tasks are sorted by the
+p->se.vruntime key (there is a subtraction using rq->cfs.min_vruntime to
+account for possible wraparounds).  CFS picks the "leftmost" task from this
+tree and sticks to it.
+As the system progresses forwards, the executed tasks are put into the tree
+more and more to the right --- slowly but surely giving a chance for every task
+to become the "leftmost task" and thus get on the CPU within a deterministic
+amount of time.
+
+Summing up, CFS works like this: it runs a task a bit, and when the task
+schedules (or a scheduler tick happens) the task's CPU usage is "accounted
+for": the (small) time it just spent using the physical CPU is added to
+p->se.vruntime.  Once p->se.vruntime gets high enough so that another task
+becomes the "leftmost task" of the time-ordered rbtree it maintains (plus a
+small amount of "granularity" distance relative to the leftmost task so that we
+do not over-schedule tasks and trash the cache), then the new leftmost task is
+picked and the current task is preempted.
+
+
+
+4.  SOME FEATURES OF CFS
+
+CFS uses nanosecond granularity accounting and does not rely on any jiffies or
+other HZ detail.  Thus the CFS scheduler has no notion of "timeslices" in the
+way the previous scheduler had, and has no heuristics whatsoever.  There is
+only one central tunable (you have to switch on CONFIG_SCHED_DEBUG):
+
+   /proc/sys/kernel/sched_granularity_ns
+
+which can be used to tune the scheduler from "desktop" (i.e., low latencies) to
+"server" (i.e., good batching) workloads.  It defaults to a setting suitable
+for desktop workloads.  SCHED_BATCH is handled by the CFS scheduler module too.
+
+Due to its design, the CFS scheduler is not prone to any of the "attacks" that
+exist today against the heuristics of the stock scheduler: fiftyp.c, thud.c,
+chew.c, ring-test.c, massive_intr.c all work fine and do not impact
+interactivity and produce the expected behavior.
+
+The CFS scheduler has a much stronger handling of nice levels and SCHED_BATCH
+than the previous vanilla scheduler: both types of workloads are isolated much
+more aggressively.
+
+SMP load-balancing has been reworked/sanitized: the runqueue-walking
+assumptions are gone from the load-balancing code now, and iterators of the
+scheduling modules are used.  The balancing code got quite a bit simpler as a
+result.
+
+
+
+5. Scheduling policies
+
+CFS implements three scheduling policies:
+
+  - SCHED_NORMAL (traditionally called SCHED_OTHER): The scheduling
+    policy that is used for regular tasks.
+
+  - SCHED_BATCH: Does not preempt nearly as often as regular tasks
+    would, thereby allowing tasks to run longer and make better use of
+    caches but at the cost of interactivity. This is well suited for
+    batch jobs.
+
+  - SCHED_IDLE: This is even weaker than nice 19, but its not a true
+    idle timer scheduler in order to avoid to get into priority
+    inversion problems which would deadlock the machine.
+
+SCHED_FIFO/_RR are implemented in sched_rt.c and are as specified by
+POSIX.
+
+The command chrt from util-linux-ng 2.13.1.1 can set all of these except
+SCHED_IDLE.
 
-Group scheduler tunables:
 
-When CONFIG_FAIR_USER_SCHED is defined, a directory is created in sysfs for
-each new user and a "cpu_share" file is added in that directory.
+
+6.  SCHEDULING CLASSES
+
+The new CFS scheduler has been designed in such a way to introduce "Scheduling
+Classes," an extensible hierarchy of scheduler modules.  These modules
+encapsulate scheduling policy details and are handled by the scheduler core
+without the core code assuming too much about them.
+
+sched_fair.c implements the CFS scheduler described above.
+
+sched_rt.c implements SCHED_FIFO and SCHED_RR semantics, in a simpler way than
+the previous vanilla scheduler did.  It uses 100 runqueues (for all 100 RT
+priority levels, instead of 140 in the previous scheduler) and it needs no
+expired array.
+
+Scheduling classes are implemented through the sched_class structure, which
+contains hooks to functions that must be called whenever an interesting event
+occurs.
+
+This is the (partial) list of the hooks:
+
+ - enqueue_task(...)
+
+   Called when a task enters a runnable state.
+   It puts the scheduling entity (task) into the red-black tree and
+   increments the nr_running variable.
+
+ - dequeue_tree(...)
+
+   When a task is no longer runnable, this function is called to keep the
+   corresponding scheduling entity out of the red-black tree.  It decrements
+   the nr_running variable.
+
+ - yield_task(...)
+
+   This function is basically just a dequeue followed by an enqueue, unless the
+   compat_yield sysctl is turned on; in that case, it places the scheduling
+   entity at the right-most end of the red-black tree.
+
+ - check_preempt_curr(...)
+
+   This function checks if a task that entered the runnable state should
+   preempt the currently running task.
+
+ - pick_next_task(...)
+
+   This function chooses the most appropriate task eligible to run next.
+
+ - set_curr_task(...)
+
+   This function is called when a task changes its scheduling class or changes
+   its task group.
+
+ - task_tick(...)
+
+   This function is mostly called from time tick functions; it might lead to
+   process switch.  This drives the running preemption.
+
+ - task_new(...)
+
+   The core scheduler gives the scheduling module an opportunity to manage new
+   task startup.  The CFS scheduling module uses it for group scheduling, while
+   the scheduling module for a real-time task does not use it.
+
+
+
+7.  GROUP SCHEDULER EXTENSIONS TO CFS
+
+Normally, the scheduler operates on individual tasks and strives to provide
+fair CPU time to each task.  Sometimes, it may be desirable to group tasks and
+provide fair CPU time to each such task group.  For example, it may be
+desirable to first provide fair CPU time to each user on the system and then to
+each task belonging to a user.
+
+CONFIG_GROUP_SCHED strives to achieve exactly that.  It lets tasks to be
+grouped and divides CPU time fairly among such groups.
+
+CONFIG_RT_GROUP_SCHED permits to group real-time (i.e., SCHED_FIFO and
+SCHED_RR) tasks.
+
+CONFIG_FAIR_GROUP_SCHED permits to group CFS (i.e., SCHED_NORMAL and
+SCHED_BATCH) tasks.
+
+At present, there are two (mutually exclusive) mechanisms to group tasks for
+CPU bandwidth control purposes:
+
+ - Based on user id (CONFIG_USER_SCHED)
+
+   With this option, tasks are grouped according to their user id.
+
+ - Based on "cgroup" pseudo filesystem (CONFIG_CGROUP_SCHED)
+
+   This options needs CONFIG_CGROUPS to be defined, and lets the administrator
+   create arbitrary groups of tasks, using the "cgroup" pseudo filesystem.  See
+   Documentation/cgroups.txt for more information about this filesystem.
+
+Only one of these options to group tasks can be chosen and not both.
+
+When CONFIG_USER_SCHED is defined, a directory is created in sysfs for each new
+user and a "cpu_share" file is added in that directory.
 
        # cd /sys/kernel/uids
        # cat 512/cpu_share             # Display user 512's CPU share
@@ -155,16 +246,14 @@ each new user and a "cpu_share" file is added in that directory.
        2048
        #
 
-CPU bandwidth between two users are divided in the ratio of their CPU shares.
-For ex: if you would like user "root" to get twice the bandwidth of user
-"guest", then set the cpu_share for both the users such that "root"'s
-cpu_share is twice "guest"'s cpu_share
-
+CPU bandwidth between two users is divided in the ratio of their CPU shares.
+For example: if you would like user "root" to get twice the bandwidth of user
+"guest," then set the cpu_share for both the users such that "root"'s cpu_share
+is twice "guest"'s cpu_share.
 
-When CONFIG_FAIR_CGROUP_SCHED is defined, a "cpu.shares" file is created
-for each group created using the pseudo filesystem. See example steps
-below to create task groups and modify their CPU share using the "cgroups"
-pseudo filesystem
+When CONFIG_CGROUP_SCHED is defined, a "cpu.shares" file is created for each
+group created using the pseudo filesystem.  See example steps below to create
+task groups and modify their CPU share using the "cgroups" pseudo filesystem.
 
        # mkdir /dev/cpuctl
        # mount -t cgroup -ocpu none /dev/cpuctl
index 75143f0c23b685f95292c2764172350adacafcc8..38d324d62b253be77166a40347583b11b1490754 100644 (file)
@@ -436,6 +436,42 @@ Other:
     was updated to remove all vports for the fc_host as well.
 
 
+Transport supplied functions
+----------------------------
+
+The following functions are supplied by the FC-transport for use by LLDs.
+
+   fc_vport_create - create a vport
+   fc_vport_terminate - detach and remove a vport
+
+Details:
+
+/**
+ * fc_vport_create - Admin App or LLDD requests creation of a vport
+ * @shost:     scsi host the virtual port is connected to.
+ * @ids:       The world wide names, FC4 port roles, etc for
+ *              the virtual port.
+ *
+ * Notes:
+ *     This routine assumes no locks are held on entry.
+ */
+struct fc_vport *
+fc_vport_create(struct Scsi_Host *shost, struct fc_vport_identifiers *ids)
+
+/**
+ * fc_vport_terminate - Admin App or LLDD requests termination of a vport
+ * @vport:      fc_vport to be terminated
+ *
+ * Calls the LLDD vport_delete() function, then deallocates and removes
+ * the vport from the shost and object tree.
+ *
+ * Notes:
+ *      This routine assumes no locks are held on entry.
+ */
+int
+fc_vport_terminate(struct fc_vport *vport)
+
+
 Credits
 =======
 The following people have contributed to this document:
diff --git a/Documentation/x86/00-INDEX b/Documentation/x86/00-INDEX
new file mode 100644 (file)
index 0000000..dbe3377
--- /dev/null
@@ -0,0 +1,4 @@
+00-INDEX
+       - this file
+mtrr.txt
+       - how to use x86 Memory Type Range Registers to increase performance
similarity index 99%
rename from Documentation/x86/i386/boot.txt
rename to Documentation/x86/boot.txt
index 147bfe511cdda0d923ca1094a27daac02225af53..83c0033ee9e01d26866494b58115a1da9b2c429a 100644 (file)
@@ -308,7 +308,7 @@ Protocol:   2.00+
 
 Field name:    start_sys
 Type:          read
-Offset/size:   0x20c/4
+Offset/size:   0x20c/2
 Protocol:      2.00+
 
   The load low segment (0x1000).  Obsolete.
similarity index 99%
rename from Documentation/mtrr.txt
rename to Documentation/x86/mtrr.txt
index c39ac395970ecfa7ee58dada23478c886952a415..cc071dc333c213676f2af659f318d7f836f2278a 100644 (file)
@@ -18,7 +18,7 @@ Richard Gooch
   The AMD K6-2 (stepping 8 and above) and K6-3 processors have two
   MTRRs. These are supported.  The AMD Athlon family provide 8 Intel
   style MTRRs.
-  
+
   The Centaur C6 (WinChip) has 8 MCRs, allowing write-combining. These
   are supported.
 
@@ -87,7 +87,7 @@ reg00: base=0x00000000 (   0MB), size=  64MB: write-back, count=1
 reg01: base=0xfb000000 (4016MB), size=  16MB: write-combining, count=1
 reg02: base=0xfb000000 (4016MB), size=   4kB: uncachable, count=1
 
-Some cards (especially Voodoo Graphics boards) need this 4 kB area 
+Some cards (especially Voodoo Graphics boards) need this 4 kB area
 excluded from the beginning of the region because it is used for
 registers.
 
index 17965f927c1583e61281e5701b951253c95bf278..c93ff5f4c0ddc0e979daa1ad0e950c8c1c6e31c1 100644 (file)
@@ -14,6 +14,10 @@ PAT allows for different types of memory attributes. The most commonly used
 ones that will be supported at this time are Write-back, Uncached,
 Write-combined and Uncached Minus.
 
+
+PAT APIs
+--------
+
 There are many different APIs in the kernel that allows setting of memory
 attributes at the page level. In order to avoid aliasing, these interfaces
 should be used thoughtfully. Below is a table of interfaces available,
@@ -26,38 +30,38 @@ address range to avoid any aliasing.
 API                    |    RAM   |  ACPI,...  |  Reserved/Holes  |
 -----------------------|----------|------------|------------------|
                        |          |            |                  |
-ioremap                |    --    |    UC      |       UC         |
+ioremap                |    --    |    UC-     |       UC-        |
                        |          |            |                  |
 ioremap_cache          |    --    |    WB      |       WB         |
                        |          |            |                  |
-ioremap_nocache        |    --    |    UC      |       UC         |
+ioremap_nocache        |    --    |    UC-     |       UC-        |
                        |          |            |                  |
 ioremap_wc             |    --    |    --      |       WC         |
                        |          |            |                  |
-set_memory_uc          |    UC    |    --      |       --         |
+set_memory_uc          |    UC-   |    --      |       --         |
  set_memory_wb         |          |            |                  |
                        |          |            |                  |
 set_memory_wc          |    WC    |    --      |       --         |
  set_memory_wb         |          |            |                  |
                        |          |            |                  |
-pci sysfs resource     |    --    |    --      |       UC         |
+pci sysfs resource     |    --    |    --      |       UC-        |
                        |          |            |                  |
 pci sysfs resource_wc  |    --    |    --      |       WC         |
  is IORESOURCE_PREFETCH|          |            |                  |
                        |          |            |                  |
-pci proc               |    --    |    --      |       UC         |
+pci proc               |    --    |    --      |       UC-        |
  !PCIIOC_WRITE_COMBINE |          |            |                  |
                        |          |            |                  |
 pci proc               |    --    |    --      |       WC         |
  PCIIOC_WRITE_COMBINE  |          |            |                  |
                        |          |            |                  |
-/dev/mem               |    --    |    UC      |       UC         |
+/dev/mem               |    --    |  WB/WC/UC- |    WB/WC/UC-     |
  read-write            |          |            |                  |
                        |          |            |                  |
-/dev/mem               |    --    |    UC      |       UC         |
+/dev/mem               |    --    |    UC-     |       UC-        |
  mmap SYNC flag        |          |            |                  |
                        |          |            |                  |
-/dev/mem               |    --    |  WB/WC/UC  |    WB/WC/UC      |
+/dev/mem               |    --    |  WB/WC/UC- |    WB/WC/UC-     |
  mmap !SYNC flag       |          |(from exist-|  (from exist-    |
  and                   |          |  ing alias)|    ing alias)    |
  any alias to this area|          |            |                  |
@@ -68,7 +72,7 @@ pci proc               |    --    |    --      |       WC         |
  and                   |          |            |                  |
  MTRR says WB          |          |            |                  |
                        |          |            |                  |
-/dev/mem               |    --    |    --      |    UC_MINUS      |
+/dev/mem               |    --    |    --      |       UC-        |
  mmap !SYNC flag       |          |            |                  |
  no alias to this area |          |            |                  |
  and                   |          |            |                  |
@@ -98,3 +102,35 @@ types.
 
 Drivers should use set_memory_[uc|wc] to set access type for RAM ranges.
 
+
+PAT debugging
+-------------
+
+With CONFIG_DEBUG_FS enabled, PAT memtype list can be examined by
+
+# mount -t debugfs debugfs /sys/kernel/debug
+# cat /sys/kernel/debug/x86/pat_memtype_list
+PAT memtype list:
+uncached-minus @ 0x7fadf000-0x7fae0000
+uncached-minus @ 0x7fb19000-0x7fb1a000
+uncached-minus @ 0x7fb1a000-0x7fb1b000
+uncached-minus @ 0x7fb1b000-0x7fb1c000
+uncached-minus @ 0x7fb1c000-0x7fb1d000
+uncached-minus @ 0x7fb1d000-0x7fb1e000
+uncached-minus @ 0x7fb1e000-0x7fb25000
+uncached-minus @ 0x7fb25000-0x7fb26000
+uncached-minus @ 0x7fb26000-0x7fb27000
+uncached-minus @ 0x7fb27000-0x7fb28000
+uncached-minus @ 0x7fb28000-0x7fb2e000
+uncached-minus @ 0x7fb2e000-0x7fb2f000
+uncached-minus @ 0x7fb2f000-0x7fb30000
+uncached-minus @ 0x7fb31000-0x7fb32000
+uncached-minus @ 0x80000000-0x90000000
+
+This list shows physical address ranges and various PAT settings used to
+access those physical address ranges.
+
+Another, more verbose way of getting PAT related debug messages is with
+"debugpat" boot parameter. With this parameter, various debug messages are
+printed to dmesg log.
+
index b0c7b6c4abda9362e38955dfee572a064dd6b992..72ffb5373ec73ac9ee8c9d05491effa7b5f8a42c 100644 (file)
@@ -54,10 +54,6 @@ APICs
                 apicmaintimer. Useful when your PIT timer is totally
                 broken.
 
-   disable_8254_timer / enable_8254_timer
-                Enable interrupt 0 timer routing over the 8254 in addition to over
-                the IO-APIC. The kernel tries to set a sensible default.
-
 Early Console
 
    syntax: earlyprintk=vga
index 8dae4555f10e1b91f0c2eafb84f04fbf71812e55..7a03bd5a91a3eb37586c13cde383c9a162f08ee0 100644 (file)
@@ -3649,8 +3649,9 @@ M:        jmorris@namei.org
 P:     Eric Paris
 M:     eparis@parisplace.org
 L:     linux-kernel@vger.kernel.org (kernel issues)
-L:     selinux@tycho.nsa.gov (subscribers-only, general discussion)
-W:     http://www.nsa.gov/selinux
+L:     selinux@tycho.nsa.gov (subscribers-only, general discussion)
+W:     http://selinuxproject.org
+T:     git kernel.org:pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git
 S:     Supported
 
 SENSABLE PHANTOM
index ce9eceb2538e39b2356aff71e625ecb7e7752d83..16e3fbb968a8966bc58570ca117349631e81f2d7 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 27
-EXTRAVERSION = -rc9
+EXTRAVERSION =
 NAME = Rotary Wombat
 
 # *DOCUMENTATION*
index 83df541650fcec6171e919fca76d1c1acaa1009a..06b6fdab639f879d56529611381f94627ee5e52f 100644 (file)
@@ -149,6 +149,9 @@ smp_callin(void)
        atomic_inc(&init_mm.mm_count);
        current->active_mm = &init_mm;
 
+       /* inform the notifiers about the new cpu */
+       notify_cpu_starting(cpuid);
+
        /* Must have completely accurate bogos.  */
        local_irq_enable();
 
index e9842f6767f959b3cfb134b7325f4076ca1dcf89..e42a749a56dd5c85abc823e2666ff7b4683c2da0 100644 (file)
@@ -277,6 +277,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
        /*
         * Enable local interrupts.
         */
+       notify_cpu_starting(cpu);
        local_irq_enable();
        local_fiq_enable();
 
index 952a24b2f5a9c59faec140963bfe03d3aeffacb2..52e16c6436f9bac0733022622fa252d217b40369 100644 (file)
@@ -178,6 +178,7 @@ void __init smp_callin(void)
        unmask_irq(IPI_INTR_VECT);
        unmask_irq(TIMER0_INTR_VECT);
        preempt_disable();
+       notify_cpu_starting(cpu);
        local_irq_enable();
 
        cpu_set(cpu, cpu_online_map);
index d8f05e504fbf039bb85fa946c40e6ff01349d26b..1dcbb85fc4ee9f05253d5d76b5e8033b39a07cf9 100644 (file)
@@ -401,6 +401,7 @@ smp_callin (void)
        spin_lock(&vector_lock);
        /* Setup the per cpu irq handling data structures */
        __setup_vector_irq(cpuid);
+       notify_cpu_starting(cpuid);
        cpu_set(cpuid, cpu_online_map);
        per_cpu(cpu_state, cpuid) = CPU_ONLINE;
        spin_unlock(&vector_lock);
index 2c03ac1d005f44cfe9fe7ad61fa03750e9edf9e9..fc2994811f150c991986b6294538ca5b9c6a64ab 100644 (file)
@@ -498,6 +498,8 @@ static void __init smp_online(void)
 {
        int cpu_id = smp_processor_id();
 
+       notify_cpu_starting(cpu_id);
+
        local_irq_enable();
 
        /* Get our bogomips. */
index 4410f172b8abf055ca4f0bc8c339dca673d90854..7b59cfb7e6022a21cf90cbd93e8e6a2dfe3a53d3 100644 (file)
@@ -121,6 +121,8 @@ asmlinkage __cpuinit void start_secondary(void)
        cpu = smp_processor_id();
        cpu_data[cpu].udelay_val = loops_per_jiffy;
 
+       notify_cpu_starting(cpu);
+
        mp_ops->smp_finish();
        set_cpu_sibling_map(cpu);
 
index 5337ca7bb649b02999258143947751109fe6c585..c27b10a1bd79adffe0a2686b9c5baaf34d3eb724 100644 (file)
@@ -453,6 +453,7 @@ int __devinit start_secondary(void *unused)
        secondary_cpu_time_init();
 
        ipi_call_lock();
+       notify_cpu_starting(cpu);
        cpu_set(cpu, cpu_online_map);
        /* Update sibling maps */
        base = cpu_first_thread_in_core(cpu);
index 00b9b4dec5eb0850aeda9a373227b190a42e8caf..9e8b1f9b8f4d6bcfcfd477e2b965030bd236cc10 100644 (file)
@@ -585,6 +585,8 @@ int __cpuinit start_secondary(void *cpuvoid)
        /* Enable pfault pseudo page faults on this cpu. */
        pfault_init();
 
+       /* call cpu notifiers */
+       notify_cpu_starting(smp_processor_id());
        /* Mark this cpu as online */
        spin_lock(&call_lock);
        cpu_set(smp_processor_id(), cpu_online_map);
index 60c50841143e26103b02a41c04d7ff863055663e..001778f9adaf83eee6cb3766866809516d346bc0 100644 (file)
@@ -82,6 +82,8 @@ asmlinkage void __cpuinit start_secondary(void)
 
        preempt_disable();
 
+       notify_cpu_starting(smp_processor_id());
+
        local_irq_enable();
 
        calibrate_delay();
index 69596402a500092c562b3ec97e7269efcc8981ec..446767e8f5694651b914cce1c1206796bd2f103d 100644 (file)
@@ -88,6 +88,7 @@ void __init smp4d_callin(void)
        local_flush_cache_all();
        local_flush_tlb_all();
 
+       notify_cpu_starting(cpuid);
        /*
         * Unblock the master CPU _only_ when the scheduler state
         * of all secondary CPUs will be up-to-date, so after
index a14a76ac7f36464642ea95f397326c29d3967002..9964890dc1dbe521b0db97ecef41ea076da8f0ca 100644 (file)
@@ -71,6 +71,8 @@ void __cpuinit smp4m_callin(void)
        local_flush_cache_all();
        local_flush_tlb_all();
 
+       notify_cpu_starting(cpuid);
+
        /* Get our local ticker going. */
        smp_setup_percpu_timer();
 
index be2d50c3aa95caf483377b8a54c2caf121ac8117..045772142844690f2471d9330b836da594c945f8 100644 (file)
@@ -85,6 +85,7 @@ static int idle_proc(void *cpup)
        while (!cpu_isset(cpu, smp_commenced_mask))
                cpu_relax();
 
+       notify_cpu_starting(cpu);
        cpu_set(cpu, cpu_online_map);
        default_idle();
        return 0;
index ed92864d1325c09092f3e8ed4918f26341f23161..97f0d2b6dc0cb2b35504cf0cb6e03d1571bae2c6 100644 (file)
@@ -29,6 +29,7 @@ config X86
        select HAVE_FTRACE
        select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64)
        select HAVE_ARCH_KGDB if !X86_VOYAGER
+       select HAVE_ARCH_TRACEHOOK
        select HAVE_GENERIC_DMA_COHERENT if X86_32
        select HAVE_EFFICIENT_UNALIGNED_ACCESS
 
@@ -1020,7 +1021,7 @@ config HAVE_ARCH_ALLOC_REMAP
 
 config ARCH_FLATMEM_ENABLE
        def_bool y
-       depends on X86_32 && ARCH_SELECT_MEMORY_MODEL && X86_PC && !NUMA
+       depends on X86_32 && ARCH_SELECT_MEMORY_MODEL && !NUMA
 
 config ARCH_DISCONTIGMEM_ENABLE
        def_bool y
@@ -1036,7 +1037,7 @@ config ARCH_SPARSEMEM_DEFAULT
 
 config ARCH_SPARSEMEM_ENABLE
        def_bool y
-       depends on X86_64 || NUMA || (EXPERIMENTAL && X86_PC)
+       depends on X86_64 || NUMA || (EXPERIMENTAL && X86_PC) || X86_GENERICARCH
        select SPARSEMEM_STATIC if X86_32
        select SPARSEMEM_VMEMMAP_ENABLE if X86_64
 
@@ -1117,10 +1118,10 @@ config MTRR
          You can safely say Y even if your machine doesn't have MTRRs, you'll
          just add about 9 KB to your kernel.
 
-         See <file:Documentation/mtrr.txt> for more information.
+         See <file:Documentation/x86/mtrr.txt> for more information.
 
 config MTRR_SANITIZER
-       bool
+       def_bool y
        prompt "MTRR cleanup support"
        depends on MTRR
        help
@@ -1131,7 +1132,7 @@ config MTRR_SANITIZER
          The largest mtrr entry size for a continous block can be set with
          mtrr_chunk_size.
 
-         If unsure, say N.
+         If unsure, say Y.
 
 config MTRR_SANITIZER_ENABLE_DEFAULT
        int "MTRR cleanup enable value (0-1)"
@@ -1191,7 +1192,6 @@ config IRQBALANCE
 config SECCOMP
        def_bool y
        prompt "Enable seccomp to safely compute untrusted bytecode"
-       depends on PROC_FS
        help
          This kernel feature is useful for number crunching applications
          that may need to compute untrusted bytecode during their
@@ -1199,7 +1199,7 @@ config SECCOMP
          the process as file descriptors supporting the read/write
          syscalls, it's possible to isolate those applications in
          their own address space using seccomp. Once seccomp is
-         enabled via /proc/<pid>/seccomp, it cannot be disabled
+         enabled via prctl(PR_SET_SECCOMP), it cannot be disabled
          and the task is only allowed to execute a few safe syscalls
          defined by each seccomp mode.
 
@@ -1356,14 +1356,14 @@ config PHYSICAL_ALIGN
          Don't change this unless you know what you are doing.
 
 config HOTPLUG_CPU
-       bool "Support for suspend on SMP and hot-pluggable CPUs (EXPERIMENTAL)"
-       depends on SMP && HOTPLUG && EXPERIMENTAL && !X86_VOYAGER
+       bool "Support for hot-pluggable CPUs"
+       depends on SMP && HOTPLUG && !X86_VOYAGER
        ---help---
-         Say Y here to experiment with turning CPUs off and on, and to
-         enable suspend on SMP systems. CPUs can be controlled through
-         /sys/devices/system/cpu.
-         Say N if you want to disable CPU hotplug and don't need to
-         suspend.
+         Say Y here to allow turning CPUs off and on. CPUs can be
+         controlled through /sys/devices/system/cpu.
+         ( Note: power management support will enable this option
+           automatically on SMP systems. )
+         Say N if you want to disable CPU hotplug.
 
 config COMPAT_VDSO
        def_bool y
@@ -1378,6 +1378,51 @@ config COMPAT_VDSO
 
          If unsure, say Y.
 
+config CMDLINE_BOOL
+       bool "Built-in kernel command line"
+       default n
+       help
+         Allow for specifying boot arguments to the kernel at
+         build time.  On some systems (e.g. embedded ones), it is
+         necessary or convenient to provide some or all of the
+         kernel boot arguments with the kernel itself (that is,
+         to not rely on the boot loader to provide them.)
+
+         To compile command line arguments into the kernel,
+         set this option to 'Y', then fill in the
+         the boot arguments in CONFIG_CMDLINE.
+
+         Systems with fully functional boot loaders (i.e. non-embedded)
+         should leave this option set to 'N'.
+
+config CMDLINE
+       string "Built-in kernel command string"
+       depends on CMDLINE_BOOL
+       default ""
+       help
+         Enter arguments here that should be compiled into the kernel
+         image and used at boot time.  If the boot loader provides a
+         command line at boot time, it is appended to this string to
+         form the full kernel command line, when the system boots.
+
+         However, you can use the CONFIG_CMDLINE_OVERRIDE option to
+         change this behavior.
+
+         In most cases, the command line (whether built-in or provided
+         by the boot loader) should specify the device for the root
+         file system.
+
+config CMDLINE_OVERRIDE
+       bool "Built-in command line overrides boot loader arguments"
+       default n
+       depends on CMDLINE_BOOL
+       help
+         Set this option to 'Y' to have the kernel ignore the boot loader
+         command line, and use ONLY the built-in command line.
+
+         This is used to work around broken boot loaders.  This should
+         be set to 'N' under normal conditions.
+
 endmenu
 
 config ARCH_ENABLE_MEMORY_HOTPLUG
@@ -1773,7 +1818,7 @@ config COMPAT_FOR_U64_ALIGNMENT
 
 config SYSVIPC_COMPAT
        def_bool y
-       depends on X86_64 && COMPAT && SYSVIPC
+       depends on COMPAT && SYSVIPC
 
 endmenu
 
index b225219c448ca4cc44c7de2402b8c894e8b5da3e..60a85768cfcba7b78c15f183fe99017e35792880 100644 (file)
@@ -418,3 +418,21 @@ config X86_MINIMUM_CPU_FAMILY
 config X86_DEBUGCTLMSR
        def_bool y
        depends on !(MK6 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MCYRIXIII || M586MMX || M586TSC || M586 || M486 || M386)
+
+config X86_DS
+       bool "Debug Store support"
+       default y
+       help
+         Add support for Debug Store.
+         This allows the kernel to provide a memory buffer to the hardware
+         to store various profiling and tracing events.
+
+config X86_PTRACE_BTS
+       bool "ptrace interface to Branch Trace Store"
+       default y
+       depends on (X86_DS && X86_DEBUGCTLMSR)
+       help
+         Add a ptrace interface to allow collecting an execution trace
+         of the traced task.
+         This collects control flow changes in a (cyclic) buffer and allows
+         debuggers to fill in the gaps and show an execution trace of the debuggee.
index ba7736cf2ec73e8977e447a8ab852d083f079c42..29c5fbf08392359ec77f4149b7b45c24cd8d071b 100644 (file)
@@ -137,14 +137,15 @@ relocated:
  */
        movl output_len(%ebx), %eax
        pushl %eax
+                       # push arguments for decompress_kernel:
        pushl %ebp      # output address
        movl input_len(%ebx), %eax
        pushl %eax      # input_len
        leal input_data(%ebx), %eax
        pushl %eax      # input_data
        leal boot_heap(%ebx), %eax
-       pushl %eax      # heap area as third argument
-       pushl %esi      # real mode pointer as second arg
+       pushl %eax      # heap area
+       pushl %esi      # real mode pointer
        call decompress_kernel
        addl $20, %esp
        popl %ecx
index 9fea737064798bfd10ab78cf729b14cfd8b87681..5780d361105bf4863328243386ed69ecdbc89889 100644 (file)
@@ -16,7 +16,7 @@
  */
 #undef CONFIG_PARAVIRT
 #ifdef CONFIG_X86_32
-#define _ASM_DESC_H_ 1
+#define ASM_X86__DESC_H 1
 #endif
 
 #ifdef CONFIG_X86_64
@@ -27,7 +27,7 @@
 #include <linux/linkage.h>
 #include <linux/screen_info.h>
 #include <linux/elf.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/page.h>
 #include <asm/boot.h>
 #include <asm/bootparam.h>
@@ -251,7 +251,7 @@ static void __putstr(int error, const char *s)
                                y--;
                        }
                } else {
-                       vidmem [(x + cols * y) * 2] = c;
+                       vidmem[(x + cols * y) * 2] = c;
                        if (++x >= cols) {
                                x = 0;
                                if (++y >= lines) {
@@ -277,7 +277,8 @@ static void *memset(void *s, int c, unsigned n)
        int i;
        char *ss = s;
 
-       for (i = 0; i < n; i++) ss[i] = c;
+       for (i = 0; i < n; i++)
+               ss[i] = c;
        return s;
 }
 
@@ -287,7 +288,8 @@ static void *memcpy(void *dest, const void *src, unsigned n)
        const char *s = src;
        char *d = dest;
 
-       for (i = 0; i < n; i++) d[i] = s[i];
+       for (i = 0; i < n; i++)
+               d[i] = s[i];
        return dest;
 }
 
index af86e431acfae2af91957a9932c3bf5fb96bd5fb..b993062e9a5f7fae2d2492abd78cfb9933a0f01a 100644 (file)
@@ -30,7 +30,6 @@ SYSSEG                = DEF_SYSSEG            /* system loaded at 0x10000 (65536) */
 SYSSIZE                = DEF_SYSSIZE           /* system size: # of 16-byte clicks */
                                        /* to be loaded */
 ROOT_DEV       = 0                     /* ROOT_DEV is now written by "build" */
-SWAP_DEV       = 0                     /* SWAP_DEV is now written by "build" */
 
 #ifndef SVGA_MODE
 #define SVGA_MODE ASK_VGA
index 104275e191a8edc97d2de46c390c011f85206c8a..ef9a52005ec9f726dbf018d43021fd1b3bf3edf8 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27-rc4
-# Mon Aug 25 15:04:00 2008
+# Linux kernel version: 2.6.27-rc5
+# Wed Sep  3 17:23:09 2008
 #
 # CONFIG_64BIT is not set
 CONFIG_X86_32=y
@@ -202,7 +202,7 @@ CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 # CONFIG_M586 is not set
 # CONFIG_M586TSC is not set
 # CONFIG_M586MMX is not set
-# CONFIG_M686 is not set
+CONFIG_M686=y
 # CONFIG_MPENTIUMII is not set
 # CONFIG_MPENTIUMIII is not set
 # CONFIG_MPENTIUMM is not set
@@ -221,13 +221,14 @@ CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 # CONFIG_MVIAC3_2 is not set
 # CONFIG_MVIAC7 is not set
 # CONFIG_MPSC is not set
-CONFIG_MCORE2=y
+# CONFIG_MCORE2 is not set
 # CONFIG_GENERIC_CPU is not set
 CONFIG_X86_GENERIC=y
 CONFIG_X86_CPU=y
 CONFIG_X86_CMPXCHG=y
 CONFIG_X86_L1_CACHE_SHIFT=7
 CONFIG_X86_XADD=y
+# CONFIG_X86_PPRO_FENCE is not set
 CONFIG_X86_WP_WORKS_OK=y
 CONFIG_X86_INVLPG=y
 CONFIG_X86_BSWAP=y
@@ -235,14 +236,15 @@ CONFIG_X86_POPAD_OK=y
 CONFIG_X86_INTEL_USERCOPY=y
 CONFIG_X86_USE_PPRO_CHECKSUM=y
 CONFIG_X86_TSC=y
+CONFIG_X86_CMOV=y
 CONFIG_X86_MINIMUM_CPU_FAMILY=4
 CONFIG_X86_DEBUGCTLMSR=y
 CONFIG_HPET_TIMER=y
 CONFIG_HPET_EMULATE_RTC=y
 CONFIG_DMI=y
 # CONFIG_IOMMU_HELPER is not set
-CONFIG_NR_CPUS=4
-# CONFIG_SCHED_SMT is not set
+CONFIG_NR_CPUS=64
+CONFIG_SCHED_SMT=y
 CONFIG_SCHED_MC=y
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
@@ -254,7 +256,8 @@ CONFIG_VM86=y
 # CONFIG_TOSHIBA is not set
 # CONFIG_I8K is not set
 CONFIG_X86_REBOOTFIXUPS=y
-# CONFIG_MICROCODE is not set
+CONFIG_MICROCODE=y
+CONFIG_MICROCODE_OLD_INTERFACE=y
 CONFIG_X86_MSR=y
 CONFIG_X86_CPUID=y
 # CONFIG_NOHIGHMEM is not set
@@ -2115,7 +2118,7 @@ CONFIG_IO_DELAY_0X80=y
 CONFIG_DEFAULT_IO_DELAY_TYPE=0
 CONFIG_DEBUG_BOOT_PARAMS=y
 # CONFIG_CPA_DEBUG is not set
-# CONFIG_OPTIMIZE_INLINING is not set
+CONFIG_OPTIMIZE_INLINING=y
 
 #
 # Security options
index 678c8acefe04da2ed74ee16e8f64077190e3f5f9..e620ea6e2a7a7d7093cdfb829a39487fe2645ee7 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27-rc4
-# Mon Aug 25 14:40:46 2008
+# Linux kernel version: 2.6.27-rc5
+# Wed Sep  3 17:13:39 2008
 #
 CONFIG_64BIT=y
 # CONFIG_X86_32 is not set
@@ -218,17 +218,14 @@ CONFIG_X86_PC=y
 # CONFIG_MVIAC3_2 is not set
 # CONFIG_MVIAC7 is not set
 # CONFIG_MPSC is not set
-CONFIG_MCORE2=y
-# CONFIG_GENERIC_CPU is not set
+# CONFIG_MCORE2 is not set
+CONFIG_GENERIC_CPU=y
 CONFIG_X86_CPU=y
-CONFIG_X86_L1_CACHE_BYTES=64
-CONFIG_X86_INTERNODE_CACHE_BYTES=64
+CONFIG_X86_L1_CACHE_BYTES=128
+CONFIG_X86_INTERNODE_CACHE_BYTES=128
 CONFIG_X86_CMPXCHG=y
-CONFIG_X86_L1_CACHE_SHIFT=6
+CONFIG_X86_L1_CACHE_SHIFT=7
 CONFIG_X86_WP_WORKS_OK=y
-CONFIG_X86_INTEL_USERCOPY=y
-CONFIG_X86_USE_PPRO_CHECKSUM=y
-CONFIG_X86_P6_NOP=y
 CONFIG_X86_TSC=y
 CONFIG_X86_CMPXCHG64=y
 CONFIG_X86_CMOV=y
@@ -243,9 +240,8 @@ CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT=y
 CONFIG_AMD_IOMMU=y
 CONFIG_SWIOTLB=y
 CONFIG_IOMMU_HELPER=y
-# CONFIG_MAXSMP is not set
-CONFIG_NR_CPUS=4
-# CONFIG_SCHED_SMT is not set
+CONFIG_NR_CPUS=64
+CONFIG_SCHED_SMT=y
 CONFIG_SCHED_MC=y
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
@@ -254,7 +250,8 @@ CONFIG_X86_LOCAL_APIC=y
 CONFIG_X86_IO_APIC=y
 # CONFIG_X86_MCE is not set
 # CONFIG_I8K is not set
-# CONFIG_MICROCODE is not set
+CONFIG_MICROCODE=y
+CONFIG_MICROCODE_OLD_INTERFACE=y
 CONFIG_X86_MSR=y
 CONFIG_X86_CPUID=y
 CONFIG_NUMA=y
@@ -290,7 +287,7 @@ CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
 CONFIG_MTRR=y
 # CONFIG_MTRR_SANITIZER is not set
-# CONFIG_X86_PAT is not set
+CONFIG_X86_PAT=y
 CONFIG_EFI=y
 CONFIG_SECCOMP=y
 # CONFIG_HZ_100 is not set
@@ -2089,7 +2086,7 @@ CONFIG_IO_DELAY_0X80=y
 CONFIG_DEFAULT_IO_DELAY_TYPE=0
 CONFIG_DEBUG_BOOT_PARAMS=y
 # CONFIG_CPA_DEBUG is not set
-# CONFIG_OPTIMIZE_INLINING is not set
+CONFIG_OPTIMIZE_INLINING=y
 
 #
 # Security options
index 3874c2de54036e125a7f4772d93f37fa277e5c11..903de4aa509496205cf792980d1b6f57b3d87177 100644 (file)
@@ -10,6 +10,8 @@ obj-$(CONFIG_CRYPTO_AES_X86_64) += aes-x86_64.o
 obj-$(CONFIG_CRYPTO_TWOFISH_X86_64) += twofish-x86_64.o
 obj-$(CONFIG_CRYPTO_SALSA20_X86_64) += salsa20-x86_64.o
 
+obj-$(CONFIG_CRYPTO_CRC32C_INTEL) += crc32c-intel.o
+
 aes-i586-y := aes-i586-asm_32.o aes_glue.o
 twofish-i586-y := twofish-i586-asm_32.o twofish_glue.o
 salsa20-i586-y := salsa20-i586-asm_32.o salsa20_glue.o
diff --git a/arch/x86/crypto/crc32c-intel.c b/arch/x86/crypto/crc32c-intel.c
new file mode 100644 (file)
index 0000000..070afc5
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * Using hardware provided CRC32 instruction to accelerate the CRC32 disposal.
+ * CRC32C polynomial:0x1EDC6F41(BE)/0x82F63B78(LE)
+ * CRC32 is a new instruction in Intel SSE4.2, the reference can be found at:
+ * http://www.intel.com/products/processor/manuals/
+ * Intel(R) 64 and IA-32 Architectures Software Developer's Manual
+ * Volume 2A: Instruction Set Reference, A-M
+ *
+ * Copyright (c) 2008 Austin Zhang <austin_zhang@linux.intel.com>
+ * Copyright (c) 2008 Kent Liu <kent.liu@intel.com>
+ *
+ * This program 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.
+ *
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <crypto/internal/hash.h>
+
+#include <asm/cpufeature.h>
+
+#define CHKSUM_BLOCK_SIZE      1
+#define CHKSUM_DIGEST_SIZE     4
+
+#define SCALE_F        sizeof(unsigned long)
+
+#ifdef CONFIG_X86_64
+#define REX_PRE "0x48, "
+#else
+#define REX_PRE
+#endif
+
+static u32 crc32c_intel_le_hw_byte(u32 crc, unsigned char const *data, size_t length)
+{
+       while (length--) {
+               __asm__ __volatile__(
+                       ".byte 0xf2, 0xf, 0x38, 0xf0, 0xf1"
+                       :"=S"(crc)
+                       :"0"(crc), "c"(*data)
+               );
+               data++;
+       }
+
+       return crc;
+}
+
+static u32 __pure crc32c_intel_le_hw(u32 crc, unsigned char const *p, size_t len)
+{
+       unsigned int iquotient = len / SCALE_F;
+       unsigned int iremainder = len % SCALE_F;
+       unsigned long *ptmp = (unsigned long *)p;
+
+       while (iquotient--) {
+               __asm__ __volatile__(
+                       ".byte 0xf2, " REX_PRE "0xf, 0x38, 0xf1, 0xf1;"
+                       :"=S"(crc)
+                       :"0"(crc), "c"(*ptmp)
+               );
+               ptmp++;
+       }
+
+       if (iremainder)
+               crc = crc32c_intel_le_hw_byte(crc, (unsigned char *)ptmp,
+                                iremainder);
+
+       return crc;
+}
+
+/*
+ * Setting the seed allows arbitrary accumulators and flexible XOR policy
+ * If your algorithm starts with ~0, then XOR with ~0 before you set
+ * the seed.
+ */
+static int crc32c_intel_setkey(struct crypto_ahash *hash, const u8 *key,
+                       unsigned int keylen)
+{
+       u32 *mctx = crypto_ahash_ctx(hash);
+
+       if (keylen != sizeof(u32)) {
+               crypto_ahash_set_flags(hash, CRYPTO_TFM_RES_BAD_KEY_LEN);
+               return -EINVAL;
+       }
+       *mctx = le32_to_cpup((__le32 *)key);
+       return 0;
+}
+
+static int crc32c_intel_init(struct ahash_request *req)
+{
+       u32 *mctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
+       u32 *crcp = ahash_request_ctx(req);
+
+       *crcp = *mctx;
+
+       return 0;
+}
+
+static int crc32c_intel_update(struct ahash_request *req)
+{
+       struct crypto_hash_walk walk;
+       u32 *crcp = ahash_request_ctx(req);
+       u32 crc = *crcp;
+       int nbytes;
+
+       for (nbytes = crypto_hash_walk_first(req, &walk); nbytes;
+          nbytes = crypto_hash_walk_done(&walk, 0))
+       crc = crc32c_intel_le_hw(crc, walk.data, nbytes);
+
+       *crcp = crc;
+       return 0;
+}
+
+static int crc32c_intel_final(struct ahash_request *req)
+{
+       u32 *crcp = ahash_request_ctx(req);
+
+       *(__le32 *)req->result = ~cpu_to_le32p(crcp);
+       return 0;
+}
+
+static int crc32c_intel_digest(struct ahash_request *req)
+{
+       struct crypto_hash_walk walk;
+       u32 *mctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
+       u32 crc = *mctx;
+       int nbytes;
+
+       for (nbytes = crypto_hash_walk_first(req, &walk); nbytes;
+          nbytes = crypto_hash_walk_done(&walk, 0))
+               crc = crc32c_intel_le_hw(crc, walk.data, nbytes);
+
+       *(__le32 *)req->result = ~cpu_to_le32(crc);
+       return 0;
+}
+
+static int crc32c_intel_cra_init(struct crypto_tfm *tfm)
+{
+       u32 *key = crypto_tfm_ctx(tfm);
+
+       *key = ~0;
+
+       tfm->crt_ahash.reqsize = sizeof(u32);
+
+       return 0;
+}
+
+static struct crypto_alg alg = {
+       .cra_name               =       "crc32c",
+       .cra_driver_name        =       "crc32c-intel",
+       .cra_priority           =       200,
+       .cra_flags              =       CRYPTO_ALG_TYPE_AHASH,
+       .cra_blocksize          =       CHKSUM_BLOCK_SIZE,
+       .cra_alignmask          =       3,
+       .cra_ctxsize            =       sizeof(u32),
+       .cra_module             =       THIS_MODULE,
+       .cra_list               =       LIST_HEAD_INIT(alg.cra_list),
+       .cra_init               =       crc32c_intel_cra_init,
+       .cra_type               =       &crypto_ahash_type,
+       .cra_u                  =       {
+               .ahash = {
+                       .digestsize    =       CHKSUM_DIGEST_SIZE,
+                       .setkey        =       crc32c_intel_setkey,
+                       .init          =       crc32c_intel_init,
+                       .update        =       crc32c_intel_update,
+                       .final         =       crc32c_intel_final,
+                       .digest        =       crc32c_intel_digest,
+               }
+       }
+};
+
+
+static int __init crc32c_intel_mod_init(void)
+{
+       if (cpu_has_xmm4_2)
+               return crypto_register_alg(&alg);
+       else
+               return -ENODEV;
+}
+
+static void __exit crc32c_intel_mod_fini(void)
+{
+       crypto_unregister_alg(&alg);
+}
+
+module_init(crc32c_intel_mod_init);
+module_exit(crc32c_intel_mod_fini);
+
+MODULE_AUTHOR("Austin Zhang <austin.zhang@intel.com>, Kent Liu <kent.liu@intel.com>");
+MODULE_DESCRIPTION("CRC32c (Castagnoli) optimization using Intel Hardware.");
+MODULE_LICENSE("GPL");
+
+MODULE_ALIAS("crc32c");
+MODULE_ALIAS("crc32c-intel");
+
index a0e1dbe67dc145cd437661ea2f472c9865e08578..127ec3f072144b7976d19533989cd97cc41da327 100644 (file)
@@ -85,8 +85,10 @@ static void dump_thread32(struct pt_regs *regs, struct user32 *dump)
        dump->regs.ax = regs->ax;
        dump->regs.ds = current->thread.ds;
        dump->regs.es = current->thread.es;
-       asm("movl %%fs,%0" : "=r" (fs)); dump->regs.fs = fs;
-       asm("movl %%gs,%0" : "=r" (gs)); dump->regs.gs = gs;
+       savesegment(fs, fs);
+       dump->regs.fs = fs;
+       savesegment(gs, gs);
+       dump->regs.gs = gs;
        dump->regs.orig_ax = regs->orig_ax;
        dump->regs.ip = regs->ip;
        dump->regs.cs = regs->cs;
@@ -430,8 +432,9 @@ beyond_if:
        current->mm->start_stack =
                (unsigned long)create_aout_tables((char __user *)bprm->p, bprm);
        /* start thread */
-       asm volatile("movl %0,%%fs" :: "r" (0)); \
-       asm volatile("movl %0,%%es; movl %0,%%ds": :"r" (__USER32_DS));
+       loadsegment(fs, 0);
+       loadsegment(ds, __USER32_DS);
+       loadsegment(es, __USER32_DS);
        load_gs_index(0);
        (regs)->ip = ex.a_entry;
        (regs)->sp = current->mm->start_stack;
index 20af4c79579a88ce1da6860e774c7440bc793b56..f1a2ac777fafa0a6b6f14b8296eae650eb45e6ee 100644 (file)
@@ -206,7 +206,7 @@ struct rt_sigframe
        { unsigned int cur;                                             \
          unsigned short pre;                                           \
          err |= __get_user(pre, &sc->seg);                             \
-         asm volatile("movl %%" #seg ",%0" : "=r" (cur));              \
+         savesegment(seg, cur);                                        \
          pre |= mask;                                                  \
          if (pre != cur) loadsegment(seg, pre); }
 
@@ -235,7 +235,7 @@ static int ia32_restore_sigcontext(struct pt_regs *regs,
         */
        err |= __get_user(gs, &sc->gs);
        gs |= 3;
-       asm("movl %%gs,%0" : "=r" (oldgs));
+       savesegment(gs, oldgs);
        if (gs != oldgs)
                load_gs_index(gs);
 
@@ -355,14 +355,13 @@ static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
 {
        int tmp, err = 0;
 
-       tmp = 0;
-       __asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp));
+       savesegment(gs, tmp);
        err |= __put_user(tmp, (unsigned int __user *)&sc->gs);
-       __asm__("movl %%fs,%0" : "=r"(tmp): "0"(tmp));
+       savesegment(fs, tmp);
        err |= __put_user(tmp, (unsigned int __user *)&sc->fs);
-       __asm__("movl %%ds,%0" : "=r"(tmp): "0"(tmp));
+       savesegment(ds, tmp);
        err |= __put_user(tmp, (unsigned int __user *)&sc->ds);
-       __asm__("movl %%es,%0" : "=r"(tmp): "0"(tmp));
+       savesegment(es, tmp);
        err |= __put_user(tmp, (unsigned int __user *)&sc->es);
 
        err |= __put_user((u32)regs->di, &sc->di);
@@ -498,8 +497,8 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka,
        regs->dx = 0;
        regs->cx = 0;
 
-       asm volatile("movl %0,%%ds" :: "r" (__USER32_DS));
-       asm volatile("movl %0,%%es" :: "r" (__USER32_DS));
+       loadsegment(ds, __USER32_DS);
+       loadsegment(es, __USER32_DS);
 
        regs->cs = __USER32_CS;
        regs->ss = __USER32_DS;
@@ -591,8 +590,8 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        regs->dx = (unsigned long) &frame->info;
        regs->cx = (unsigned long) &frame->uc;
 
-       asm volatile("movl %0,%%ds" :: "r" (__USER32_DS));
-       asm volatile("movl %0,%%es" :: "r" (__USER32_DS));
+       loadsegment(ds, __USER32_DS);
+       loadsegment(es, __USER32_DS);
 
        regs->cs = __USER32_CS;
        regs->ss = __USER32_DS;
index d3c64088b981f02fe5614ec53c3539b5bd3b703a..beda4232ce695cc2f42aea28dea84dad02a38235 100644 (file)
@@ -556,15 +556,6 @@ asmlinkage long sys32_rt_sigqueueinfo(int pid, int sig,
        return ret;
 }
 
-/* These are here just in case some old ia32 binary calls it. */
-asmlinkage long sys32_pause(void)
-{
-       current->state = TASK_INTERRUPTIBLE;
-       schedule();
-       return -ERESTARTNOHAND;
-}
-
-
 #ifdef CONFIG_SYSCTL_SYSCALL
 struct sysctl_ia32 {
        unsigned int    name;
index c102af85df9ca4443b9b4a12db8b77ceccf90a82..7d40ef7b36e3dac8b857a9fb4013cf901cf906e9 100644 (file)
@@ -58,7 +58,6 @@ EXPORT_SYMBOL(acpi_disabled);
 #ifdef CONFIG_X86_64
 
 #include <asm/proto.h>
-#include <asm/genapic.h>
 
 #else                          /* X86 */
 
@@ -97,8 +96,6 @@ static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
 #warning ACPI uses CMPXCHG, i486 and later hardware
 #endif
 
-static int acpi_mcfg_64bit_base_addr __initdata = FALSE;
-
 /* --------------------------------------------------------------------------
                               Boot-time Configuration
    -------------------------------------------------------------------------- */
@@ -160,6 +157,8 @@ char *__init __acpi_map_table(unsigned long phys, unsigned long size)
 struct acpi_mcfg_allocation *pci_mmcfg_config;
 int pci_mmcfg_config_num;
 
+static int acpi_mcfg_64bit_base_addr __initdata = FALSE;
+
 static int __init acpi_mcfg_oem_check(struct acpi_table_mcfg *mcfg)
 {
        if (!strcmp(mcfg->header.oem_id, "SGI"))
index 65a0c1b4869636122fc22dec84de26788662a2d4..fb04e49776ba308b2cd8f86315bcb7692122ce80 100644 (file)
@@ -231,25 +231,25 @@ static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end)
                        continue;
                if (*ptr > text_end)
                        continue;
-               text_poke(*ptr, ((unsigned char []){0xf0}), 1); /* add lock prefix */
+               /* turn DS segment override prefix into lock prefix */
+               text_poke(*ptr, ((unsigned char []){0xf0}), 1);
        };
 }
 
 static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end)
 {
        u8 **ptr;
-       char insn[1];
 
        if (noreplace_smp)
                return;
 
-       add_nops(insn, 1);
        for (ptr = start; ptr < end; ptr++) {
                if (*ptr < text)
                        continue;
                if (*ptr > text_end)
                        continue;
-               text_poke(*ptr, insn, 1);
+               /* turn lock prefix into DS segment override prefix */
+               text_poke(*ptr, ((unsigned char []){0x3E}), 1);
        };
 }
 
index 44e21826db1145a00659c89c5c45232ff3e70d2a..9a32b37ee2eec2f176708d7fccd5b7dadcf0e3ab 100644 (file)
@@ -455,11 +455,11 @@ out:
                   force_iommu ||
                   valid_agp ||
                   fallback_aper_force) {
-               printk(KERN_ERR
+               printk(KERN_INFO
                        "Your BIOS doesn't leave a aperture memory hole\n");
-               printk(KERN_ERR
+               printk(KERN_INFO
                        "Please enable the IOMMU option in the BIOS setup\n");
-               printk(KERN_ERR
+               printk(KERN_INFO
                        "This costs you %d MB of RAM\n",
                                32 << fallback_aper_order);
 
index 732d1f4e10ee641020f9af9b1851be4e9bbad99e..5145a6e72bbbf7f6a4e93d85aed20c769f0883dc 100644 (file)
 #include <linux/suspend.h>
 #include <linux/kthread.h>
 #include <linux/jiffies.h>
-#include <linux/smp_lock.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
index aa89387006fe3a730b9b7eba9b7b55cc3c1beb4d..505543a75a561f1cfc207d4f88dffbd2718bc724 100644 (file)
@@ -22,7 +22,7 @@
 
 #define __NO_STUBS 1
 #undef __SYSCALL
-#undef _ASM_X86_64_UNISTD_H_
+#undef ASM_X86__UNISTD_64_H
 #define __SYSCALL(nr, sym) [nr] = 1,
 static char syscalls[] = {
 #include <asm/unistd.h>
index c639bd55391cc1e8b679e2be8ee1373e5c093e2f..fdd585f9c53dd371d41392b4e955278d913979f0 100644 (file)
@@ -25,11 +25,11 @@ x86_bios_strerror(long status)
 {
        const char *str;
        switch (status) {
-       case  0: str = "Call completed without error"; break;
-       case -1: str = "Not implemented"; break;
-       case -2: str = "Invalid argument"; break;
-       case -3: str = "Call completed with error"; break;
-       default: str = "Unknown BIOS status code"; break;
+       case  0: str = "Call completed without error";  break;
+       case -1: str = "Not implemented";               break;
+       case -2: str = "Invalid argument";              break;
+       case -3: str = "Call completed with error";     break;
+       default: str = "Unknown BIOS status code";      break;
        }
        return str;
 }
index a11f5d4477cd797432d8a54df202dd558bdec5d5..305b465889b096a5205556ca02accf1466abe780 100644 (file)
@@ -430,6 +430,49 @@ static __init int setup_noclflush(char *arg)
 }
 __setup("noclflush", setup_noclflush);
 
+struct msr_range {
+       unsigned min;
+       unsigned max;
+};
+
+static struct msr_range msr_range_array[] __cpuinitdata = {
+       { 0x00000000, 0x00000418},
+       { 0xc0000000, 0xc000040b},
+       { 0xc0010000, 0xc0010142},
+       { 0xc0011000, 0xc001103b},
+};
+
+static void __cpuinit print_cpu_msr(void)
+{
+       unsigned index;
+       u64 val;
+       int i;
+       unsigned index_min, index_max;
+
+       for (i = 0; i < ARRAY_SIZE(msr_range_array); i++) {
+               index_min = msr_range_array[i].min;
+               index_max = msr_range_array[i].max;
+               for (index = index_min; index < index_max; index++) {
+                       if (rdmsrl_amd_safe(index, &val))
+                               continue;
+                       printk(KERN_INFO " MSR%08x: %016llx\n", index, val);
+               }
+       }
+}
+
+static int show_msr __cpuinitdata;
+static __init int setup_show_msr(char *arg)
+{
+       int num;
+
+       get_option(&arg, &num);
+
+       if (num > 0)
+               show_msr = num;
+       return 1;
+}
+__setup("show_msr=", setup_show_msr);
+
 void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
 {
        if (c->x86_model_id[0])
@@ -439,6 +482,14 @@ void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
                printk(KERN_CONT " stepping %02x\n", c->x86_mask);
        else
                printk(KERN_CONT "\n");
+
+#ifdef CONFIG_SMP
+       if (c->cpu_index < show_msr)
+               print_cpu_msr();
+#else
+       if (show_msr)
+               print_cpu_msr();
+#endif
 }
 
 static __init int setup_disablecpuid(char *arg)
index f1685fb91fbd313058b92af93ee055af160a2447..b8e05ee4f7361a1dc57ce28ff9d2e5e5526f776d 100644 (file)
@@ -171,7 +171,7 @@ static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c)
        }
 
        if (c->x86 != 0xF) {
-               printk(KERN_WARNING PFX "Unknown p4-clockmod-capable CPU. Please send an e-mail to <cpufreq@lists.linux.org.uk>\n");
+               printk(KERN_WARNING PFX "Unknown p4-clockmod-capable CPU. Please send an e-mail to <cpufreq@vger.kernel.org>\n");
                return 0;
        }
 
index 15e13c01cc3621ce3d4d610ab34225437eb8f413..3b5f06423e7774f2801e31e811c631df90344e36 100644 (file)
@@ -26,7 +26,7 @@
 #include <asm/cpufeature.h>
 
 #define PFX            "speedstep-centrino: "
-#define MAINTAINER     "cpufreq@lists.linux.org.uk"
+#define MAINTAINER     "cpufreq@vger.kernel.org"
 
 #define dprintk(msg...) \
        cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-centrino", msg)
index b75f2569b8f8ba1940d55ce3616f25a91c7c6d75..f113ef4595f6ca81dd810058337f4118590083b3 100644 (file)
@@ -222,10 +222,11 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
                        set_cpu_cap(c, X86_FEATURE_BTS);
                if (!(l1 & (1<<12)))
                        set_cpu_cap(c, X86_FEATURE_PEBS);
+               ds_init_intel(c);
        }
 
        if (cpu_has_bts)
-               ds_init_intel(c);
+               ptrace_bts_init_intel(c);
 
        /*
         * See if we have a good local APIC by checking for buggy Pentia,
index cb7d3b6a80eb879670bd8a74864d01b587561dec..4e8d77f01eeb0913527373ed38a71795cc0b7be1 100644 (file)
@@ -401,12 +401,7 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base,
                tmp |= ~((1<<(hi - 1)) - 1);
 
                if (tmp != mask_lo) {
-                       static int once = 1;
-
-                       if (once) {
-                               printk(KERN_INFO "mtrr: your BIOS has set up an incorrect mask, fixing it up.\n");
-                               once = 0;
-                       }
+                       WARN_ONCE(1, KERN_INFO "mtrr: your BIOS has set up an incorrect mask, fixing it up.\n");
                        mask_lo = tmp;
                }
        }
index 84c480bb3715af21405c6d55fab0f3160cbf3a59..4c4214690dd10a4c32fc787e03bce6e7cba315d9 100644 (file)
@@ -405,9 +405,9 @@ static int mtrr_seq_show(struct seq_file *seq, void *offset)
                        }
                        /* RED-PEN: base can be > 32bit */ 
                        len += seq_printf(seq, 
-                                  "reg%02i: base=0x%05lx000 (%4luMB), size=%4lu%cB: %s, count=%d\n",
+                                  "reg%02i: base=0x%06lx000 (%5luMB), size=%5lu%cB, count=%d: %s\n",
                             i, base, base >> (20 - PAGE_SHIFT), size, factor,
-                            mtrr_attrib_to_str(type), mtrr_usage_table[i]);
+                            mtrr_usage_table[i], mtrr_attrib_to_str(type));
                }
        }
        return 0;
index 885c8265e6b5baf2178d3f8da74257635abf58d3..c78c04821ea18a58266b812fef480aa0b5ec0fbb 100644 (file)
@@ -729,7 +729,7 @@ struct var_mtrr_range_state {
        mtrr_type type;
 };
 
-struct var_mtrr_range_state __initdata range_state[RANGE_NUM];
+static struct var_mtrr_range_state __initdata range_state[RANGE_NUM];
 static int __initdata debug_print;
 
 static int __init
@@ -759,7 +759,8 @@ x86_get_mtrr_mem_range(struct res_range *range, int nr_range,
        /* take out UC ranges */
        for (i = 0; i < num_var_ranges; i++) {
                type = range_state[i].type;
-               if (type != MTRR_TYPE_UNCACHABLE)
+               if (type != MTRR_TYPE_UNCACHABLE &&
+                   type != MTRR_TYPE_WRPROT)
                        continue;
                size = range_state[i].size_pfn;
                if (!size)
@@ -836,6 +837,13 @@ static int __init enable_mtrr_cleanup_setup(char *str)
 }
 early_param("enable_mtrr_cleanup", enable_mtrr_cleanup_setup);
 
+static int __init mtrr_cleanup_debug_setup(char *str)
+{
+       debug_print = 1;
+       return 0;
+}
+early_param("mtrr_cleanup_debug", mtrr_cleanup_debug_setup);
+
 struct var_mtrr_state {
        unsigned long   range_startk;
        unsigned long   range_sizek;
@@ -898,6 +906,27 @@ set_var_mtrr_all(unsigned int address_bits)
        }
 }
 
+static unsigned long to_size_factor(unsigned long sizek, char *factorp)
+{
+       char factor;
+       unsigned long base = sizek;
+
+       if (base & ((1<<10) - 1)) {
+               /* not MB alignment */
+               factor = 'K';
+       } else if (base & ((1<<20) - 1)){
+               factor = 'M';
+               base >>= 10;
+       } else {
+               factor = 'G';
+               base >>= 20;
+       }
+
+       *factorp = factor;
+
+       return base;
+}
+
 static unsigned int __init
 range_to_mtrr(unsigned int reg, unsigned long range_startk,
              unsigned long range_sizek, unsigned char type)
@@ -919,13 +948,21 @@ range_to_mtrr(unsigned int reg, unsigned long range_startk,
                        align = max_align;
 
                sizek = 1 << align;
-               if (debug_print)
+               if (debug_print) {
+                       char start_factor = 'K', size_factor = 'K';
+                       unsigned long start_base, size_base;
+
+                       start_base = to_size_factor(range_startk, &start_factor),
+                       size_base = to_size_factor(sizek, &size_factor),
+
                        printk(KERN_DEBUG "Setting variable MTRR %d, "
-                               "base: %ldMB, range: %ldMB, type %s\n",
-                               reg, range_startk >> 10, sizek >> 10,
+                               "base: %ld%cB, range: %ld%cB, type %s\n",
+                               reg, start_base, start_factor,
+                               size_base, size_factor,
                                (type == MTRR_TYPE_UNCACHABLE)?"UC":
                                    ((type == MTRR_TYPE_WRBACK)?"WB":"Other")
                                );
+               }
                save_var_mtrr(reg++, range_startk, sizek, type);
                range_startk += sizek;
                range_sizek -= sizek;
@@ -970,6 +1007,8 @@ range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek,
        /* try to append some small hole */
        range0_basek = state->range_startk;
        range0_sizek = ALIGN(state->range_sizek, chunk_sizek);
+
+       /* no increase */
        if (range0_sizek == state->range_sizek) {
                if (debug_print)
                        printk(KERN_DEBUG "rangeX: %016lx - %016lx\n",
@@ -980,13 +1019,40 @@ range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek,
                return 0;
        }
 
-       range0_sizek -= chunk_sizek;
-       if (range0_sizek && sizek) {
-           while (range0_basek + range0_sizek > (basek + sizek)) {
-               range0_sizek -= chunk_sizek;
-               if (!range0_sizek)
-                       break;
-           }
+       /* only cut back, when it is not the last */
+       if (sizek) {
+               while (range0_basek + range0_sizek > (basek + sizek)) {
+                       if (range0_sizek >= chunk_sizek)
+                               range0_sizek -= chunk_sizek;
+                       else
+                               range0_sizek = 0;
+
+                       if (!range0_sizek)
+                               break;
+               }
+       }
+
+second_try:
+       range_basek = range0_basek + range0_sizek;
+
+       /* one hole in the middle */
+       if (range_basek > basek && range_basek <= (basek + sizek))
+               second_sizek = range_basek - basek;
+
+       if (range0_sizek > state->range_sizek) {
+
+               /* one hole in middle or at end */
+               hole_sizek = range0_sizek - state->range_sizek - second_sizek;
+
+               /* hole size should be less than half of range0 size */
+               if (hole_sizek >= (range0_sizek >> 1) &&
+                   range0_sizek >= chunk_sizek) {
+                       range0_sizek -= chunk_sizek;
+                       second_sizek = 0;
+                       hole_sizek = 0;
+
+                       goto second_try;
+               }
        }
 
        if (range0_sizek) {
@@ -996,50 +1062,28 @@ range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek,
                                (range0_basek + range0_sizek)<<10);
                state->reg = range_to_mtrr(state->reg, range0_basek,
                                range0_sizek, MTRR_TYPE_WRBACK);
-
-       }
-
-       range_basek = range0_basek + range0_sizek;
-       range_sizek = chunk_sizek;
-
-       if (range_basek + range_sizek > basek &&
-           range_basek + range_sizek <= (basek + sizek)) {
-               /* one hole */
-               second_basek = basek;
-               second_sizek = range_basek + range_sizek - basek;
        }
 
-       /* if last piece, only could one hole near end */
-       if ((second_basek || !basek) &&
-           range_sizek - (state->range_sizek - range0_sizek) - second_sizek <
-           (chunk_sizek >> 1)) {
-               /*
-                * one hole in middle (second_sizek is 0) or at end
-                * (second_sizek is 0 )
-                */
-               hole_sizek = range_sizek - (state->range_sizek - range0_sizek)
-                                - second_sizek;
-               hole_basek = range_basek + range_sizek - hole_sizek
-                                - second_sizek;
-       } else {
-               /* fallback for big hole, or several holes */
+       if (range0_sizek < state->range_sizek) {
+               /* need to handle left over */
                range_sizek = state->range_sizek - range0_sizek;
-               second_basek = 0;
-               second_sizek = 0;
+
+               if (debug_print)
+                       printk(KERN_DEBUG "range: %016lx - %016lx\n",
+                                range_basek<<10,
+                                (range_basek + range_sizek)<<10);
+               state->reg = range_to_mtrr(state->reg, range_basek,
+                                range_sizek, MTRR_TYPE_WRBACK);
        }
 
-       if (debug_print)
-               printk(KERN_DEBUG "range: %016lx - %016lx\n", range_basek<<10,
-                        (range_basek + range_sizek)<<10);
-       state->reg = range_to_mtrr(state->reg, range_basek, range_sizek,
-                                        MTRR_TYPE_WRBACK);
        if (hole_sizek) {
+               hole_basek = range_basek - hole_sizek - second_sizek;
                if (debug_print)
                        printk(KERN_DEBUG "hole: %016lx - %016lx\n",
-                                hole_basek<<10, (hole_basek + hole_sizek)<<10);
-               state->reg = range_to_mtrr(state->reg, hole_basek, hole_sizek,
-                                                MTRR_TYPE_UNCACHABLE);
-
+                                hole_basek<<10,
+                                (hole_basek + hole_sizek)<<10);
+               state->reg = range_to_mtrr(state->reg, hole_basek,
+                                hole_sizek, MTRR_TYPE_UNCACHABLE);
        }
 
        return second_sizek;
@@ -1154,11 +1198,11 @@ struct mtrr_cleanup_result {
 };
 
 /*
- * gran_size: 1M, 2M, ..., 2G
- * chunk size: gran_size, ..., 4G
- * so we need (2+13)*6
+ * gran_size: 64K, 128K, 256K, 512K, 1M, 2M, ..., 2G
+ * chunk size: gran_size, ..., 2G
+ * so we need (1+16)*8
  */
-#define NUM_RESULT     90
+#define NUM_RESULT     136
 #define PSHIFT         (PAGE_SHIFT - 10)
 
 static struct mtrr_cleanup_result __initdata result[NUM_RESULT];
@@ -1168,13 +1212,14 @@ static unsigned long __initdata min_loss_pfn[RANGE_NUM];
 static int __init mtrr_cleanup(unsigned address_bits)
 {
        unsigned long extra_remove_base, extra_remove_size;
-       unsigned long i, base, size, def, dummy;
+       unsigned long base, size, def, dummy;
        mtrr_type type;
        int nr_range, nr_range_new;
        u64 chunk_size, gran_size;
        unsigned long range_sums, range_sums_new;
        int index_good;
        int num_reg_good;
+       int i;
 
        /* extra one for all 0 */
        int num[MTRR_NUM_TYPES + 1];
@@ -1204,6 +1249,8 @@ static int __init mtrr_cleanup(unsigned address_bits)
                        continue;
                if (!size)
                        type = MTRR_NUM_TYPES;
+               if (type == MTRR_TYPE_WRPROT)
+                       type = MTRR_TYPE_UNCACHABLE;
                num[type]++;
        }
 
@@ -1216,23 +1263,57 @@ static int __init mtrr_cleanup(unsigned address_bits)
                num_var_ranges - num[MTRR_NUM_TYPES])
                return 0;
 
+       /* print original var MTRRs at first, for debugging: */
+       printk(KERN_DEBUG "original variable MTRRs\n");
+       for (i = 0; i < num_var_ranges; i++) {
+               char start_factor = 'K', size_factor = 'K';
+               unsigned long start_base, size_base;
+
+               size_base = range_state[i].size_pfn << (PAGE_SHIFT - 10);
+               if (!size_base)
+                       continue;
+
+               size_base = to_size_factor(size_base, &size_factor),
+               start_base = range_state[i].base_pfn << (PAGE_SHIFT - 10);
+               start_base = to_size_factor(start_base, &start_factor),
+               type = range_state[i].type;
+
+               printk(KERN_DEBUG "reg %d, base: %ld%cB, range: %ld%cB, type %s\n",
+                       i, start_base, start_factor,
+                       size_base, size_factor,
+                       (type == MTRR_TYPE_UNCACHABLE) ? "UC" :
+                           ((type == MTRR_TYPE_WRPROT) ? "WP" :
+                            ((type == MTRR_TYPE_WRBACK) ? "WB" : "Other"))
+                       );
+       }
+
        memset(range, 0, sizeof(range));
        extra_remove_size = 0;
-       if (mtrr_tom2) {
-               extra_remove_base = 1 << (32 - PAGE_SHIFT);
+       extra_remove_base = 1 << (32 - PAGE_SHIFT);
+       if (mtrr_tom2)
                extra_remove_size =
                        (mtrr_tom2 >> PAGE_SHIFT) - extra_remove_base;
-       }
        nr_range = x86_get_mtrr_mem_range(range, 0, extra_remove_base,
                                          extra_remove_size);
+       /*
+        * [0, 1M) should always be coverred by var mtrr with WB
+        * and fixed mtrrs should take effective before var mtrr for it
+        */
+       nr_range = add_range_with_merge(range, nr_range, 0,
+                                       (1ULL<<(20 - PAGE_SHIFT)) - 1);
+       /* sort the ranges */
+       sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL);
+
        range_sums = sum_ranges(range, nr_range);
        printk(KERN_INFO "total RAM coverred: %ldM\n",
               range_sums >> (20 - PAGE_SHIFT));
 
        if (mtrr_chunk_size && mtrr_gran_size) {
                int num_reg;
+               char gran_factor, chunk_factor, lose_factor;
+               unsigned long gran_base, chunk_base, lose_base;
 
-               debug_print = 1;
+               debug_print++;
                /* convert ranges to var ranges state */
                num_reg = x86_setup_var_mtrrs(range, nr_range, mtrr_chunk_size,
                                              mtrr_gran_size);
@@ -1256,34 +1337,48 @@ static int __init mtrr_cleanup(unsigned address_bits)
                        result[i].lose_cover_sizek =
                                (range_sums - range_sums_new) << PSHIFT;
 
-               printk(KERN_INFO "%sgran_size: %ldM \tchunk_size: %ldM \t",
-                        result[i].bad?"*BAD*":" ", result[i].gran_sizek >> 10,
-                        result[i].chunk_sizek >> 10);
-               printk(KERN_CONT "num_reg: %d  \tlose cover RAM: %s%ldM \n",
+               gran_base = to_size_factor(result[i].gran_sizek, &gran_factor),
+               chunk_base = to_size_factor(result[i].chunk_sizek, &chunk_factor),
+               lose_base = to_size_factor(result[i].lose_cover_sizek, &lose_factor),
+               printk(KERN_INFO "%sgran_size: %ld%c \tchunk_size: %ld%c \t",
+                        result[i].bad?"*BAD*":" ",
+                        gran_base, gran_factor, chunk_base, chunk_factor);
+               printk(KERN_CONT "num_reg: %d  \tlose cover RAM: %s%ld%c\n",
                         result[i].num_reg, result[i].bad?"-":"",
-                        result[i].lose_cover_sizek >> 10);
+                        lose_base, lose_factor);
                if (!result[i].bad) {
                        set_var_mtrr_all(address_bits);
                        return 1;
                }
                printk(KERN_INFO "invalid mtrr_gran_size or mtrr_chunk_size, "
                       "will find optimal one\n");
-               debug_print = 0;
+               debug_print--;
                memset(result, 0, sizeof(result[0]));
        }
 
        i = 0;
        memset(min_loss_pfn, 0xff, sizeof(min_loss_pfn));
        memset(result, 0, sizeof(result));
-       for (gran_size = (1ULL<<20); gran_size < (1ULL<<32); gran_size <<= 1) {
-               for (chunk_size = gran_size; chunk_size < (1ULL<<33);
+       for (gran_size = (1ULL<<16); gran_size < (1ULL<<32); gran_size <<= 1) {
+               char gran_factor;
+               unsigned long gran_base;
+
+               if (debug_print)
+                       gran_base = to_size_factor(gran_size >> 10, &gran_factor);
+
+               for (chunk_size = gran_size; chunk_size < (1ULL<<32);
                     chunk_size <<= 1) {
                        int num_reg;
 
-                       if (debug_print)
-                               printk(KERN_INFO
-                              "\ngran_size: %lldM   chunk_size_size: %lldM\n",
-                                      gran_size >> 20, chunk_size >> 20);
+                       if (debug_print) {
+                               char chunk_factor;
+                               unsigned long chunk_base;
+
+                               chunk_base = to_size_factor(chunk_size>>10, &chunk_factor),
+                               printk(KERN_INFO "\n");
+                               printk(KERN_INFO "gran_size: %ld%c   chunk_size: %ld%c \n",
+                                      gran_base, gran_factor, chunk_base, chunk_factor);
+                       }
                        if (i >= NUM_RESULT)
                                continue;
 
@@ -1326,12 +1421,18 @@ static int __init mtrr_cleanup(unsigned address_bits)
 
        /* print out all */
        for (i = 0; i < NUM_RESULT; i++) {
-               printk(KERN_INFO "%sgran_size: %ldM \tchunk_size: %ldM \t",
-                      result[i].bad?"*BAD* ":" ", result[i].gran_sizek >> 10,
-                      result[i].chunk_sizek >> 10);
-               printk(KERN_CONT "num_reg: %d \tlose RAM: %s%ldM\n",
-                      result[i].num_reg, result[i].bad?"-":"",
-                      result[i].lose_cover_sizek >> 10);
+               char gran_factor, chunk_factor, lose_factor;
+               unsigned long gran_base, chunk_base, lose_base;
+
+               gran_base = to_size_factor(result[i].gran_sizek, &gran_factor),
+               chunk_base = to_size_factor(result[i].chunk_sizek, &chunk_factor),
+               lose_base = to_size_factor(result[i].lose_cover_sizek, &lose_factor),
+               printk(KERN_INFO "%sgran_size: %ld%c \tchunk_size: %ld%c \t",
+                        result[i].bad?"*BAD*":" ",
+                        gran_base, gran_factor, chunk_base, chunk_factor);
+               printk(KERN_CONT "num_reg: %d  \tlose cover RAM: %s%ld%c\n",
+                        result[i].num_reg, result[i].bad?"-":"",
+                        lose_base, lose_factor);
        }
 
        /* try to find the optimal index */
@@ -1339,10 +1440,8 @@ static int __init mtrr_cleanup(unsigned address_bits)
                nr_mtrr_spare_reg = num_var_ranges - 1;
        num_reg_good = -1;
        for (i = num_var_ranges - nr_mtrr_spare_reg; i > 0; i--) {
-               if (!min_loss_pfn[i]) {
+               if (!min_loss_pfn[i])
                        num_reg_good = i;
-                       break;
-               }
        }
 
        index_good = -1;
@@ -1358,21 +1457,26 @@ static int __init mtrr_cleanup(unsigned address_bits)
        }
 
        if (index_good != -1) {
+               char gran_factor, chunk_factor, lose_factor;
+               unsigned long gran_base, chunk_base, lose_base;
+
                printk(KERN_INFO "Found optimal setting for mtrr clean up\n");
                i = index_good;
-               printk(KERN_INFO "gran_size: %ldM \tchunk_size: %ldM \t",
-                               result[i].gran_sizek >> 10,
-                               result[i].chunk_sizek >> 10);
-               printk(KERN_CONT "num_reg: %d \tlose RAM: %ldM\n",
-                               result[i].num_reg,
-                               result[i].lose_cover_sizek >> 10);
+               gran_base = to_size_factor(result[i].gran_sizek, &gran_factor),
+               chunk_base = to_size_factor(result[i].chunk_sizek, &chunk_factor),
+               lose_base = to_size_factor(result[i].lose_cover_sizek, &lose_factor),
+               printk(KERN_INFO "gran_size: %ld%c \tchunk_size: %ld%c \t",
+                        gran_base, gran_factor, chunk_base, chunk_factor);
+               printk(KERN_CONT "num_reg: %d  \tlose RAM: %ld%c\n",
+                        result[i].num_reg, lose_base, lose_factor);
                /* convert ranges to var ranges state */
                chunk_size = result[i].chunk_sizek;
                chunk_size <<= 10;
                gran_size = result[i].gran_sizek;
                gran_size <<= 10;
-               debug_print = 1;
+               debug_print++;
                x86_setup_var_mtrrs(range, nr_range, chunk_size, gran_size);
+               debug_print--;
                set_var_mtrr_all(address_bits);
                return 1;
        }
index 05cc22dbd4ffdebff8738662c74fd954be8fd432..6bff382094f58a2a40b0adebdf5fb264905614ba 100644 (file)
@@ -295,13 +295,19 @@ static int setup_k7_watchdog(unsigned nmi_hz)
        /* setup the timer */
        wrmsr(evntsel_msr, evntsel, 0);
        write_watchdog_counter(perfctr_msr, "K7_PERFCTR0",nmi_hz);
-       apic_write(APIC_LVTPC, APIC_DM_NMI);
-       evntsel |= K7_EVNTSEL_ENABLE;
-       wrmsr(evntsel_msr, evntsel, 0);
 
+       /* initialize the wd struct before enabling */
        wd->perfctr_msr = perfctr_msr;
        wd->evntsel_msr = evntsel_msr;
        wd->cccr_msr = 0;  /* unused */
+
+       /* ok, everything is initialized, announce that we're set */
+       cpu_nmi_set_wd_enabled();
+
+       apic_write(APIC_LVTPC, APIC_DM_NMI);
+       evntsel |= K7_EVNTSEL_ENABLE;
+       wrmsr(evntsel_msr, evntsel, 0);
+
        return 1;
 }
 
@@ -379,13 +385,19 @@ static int setup_p6_watchdog(unsigned nmi_hz)
        wrmsr(evntsel_msr, evntsel, 0);
        nmi_hz = adjust_for_32bit_ctr(nmi_hz);
        write_watchdog_counter32(perfctr_msr, "P6_PERFCTR0",nmi_hz);
-       apic_write(APIC_LVTPC, APIC_DM_NMI);
-       evntsel |= P6_EVNTSEL0_ENABLE;
-       wrmsr(evntsel_msr, evntsel, 0);
 
+       /* initialize the wd struct before enabling */
        wd->perfctr_msr = perfctr_msr;
        wd->evntsel_msr = evntsel_msr;
        wd->cccr_msr = 0;  /* unused */
+
+       /* ok, everything is initialized, announce that we're set */
+       cpu_nmi_set_wd_enabled();
+
+       apic_write(APIC_LVTPC, APIC_DM_NMI);
+       evntsel |= P6_EVNTSEL0_ENABLE;
+       wrmsr(evntsel_msr, evntsel, 0);
+
        return 1;
 }
 
@@ -432,6 +444,27 @@ static const struct wd_ops p6_wd_ops = {
 #define P4_CCCR_ENABLE         (1 << 12)
 #define P4_CCCR_OVF            (1 << 31)
 
+#define P4_CONTROLS 18
+static unsigned int p4_controls[18] = {
+       MSR_P4_BPU_CCCR0,
+       MSR_P4_BPU_CCCR1,
+       MSR_P4_BPU_CCCR2,
+       MSR_P4_BPU_CCCR3,
+       MSR_P4_MS_CCCR0,
+       MSR_P4_MS_CCCR1,
+       MSR_P4_MS_CCCR2,
+       MSR_P4_MS_CCCR3,
+       MSR_P4_FLAME_CCCR0,
+       MSR_P4_FLAME_CCCR1,
+       MSR_P4_FLAME_CCCR2,
+       MSR_P4_FLAME_CCCR3,
+       MSR_P4_IQ_CCCR0,
+       MSR_P4_IQ_CCCR1,
+       MSR_P4_IQ_CCCR2,
+       MSR_P4_IQ_CCCR3,
+       MSR_P4_IQ_CCCR4,
+       MSR_P4_IQ_CCCR5,
+};
 /*
  * Set up IQ_COUNTER0 to behave like a clock, by having IQ_CCCR0 filter
  * CRU_ESCR0 (with any non-null event selector) through a complemented
@@ -473,6 +506,26 @@ static int setup_p4_watchdog(unsigned nmi_hz)
                evntsel_msr = MSR_P4_CRU_ESCR0;
                cccr_msr = MSR_P4_IQ_CCCR0;
                cccr_val = P4_CCCR_OVF_PMI0 | P4_CCCR_ESCR_SELECT(4);
+
+               /*
+                * If we're on the kdump kernel or other situation, we may
+                * still have other performance counter registers set to
+                * interrupt and they'll keep interrupting forever because
+                * of the P4_CCCR_OVF quirk. So we need to ACK all the
+                * pending interrupts and disable all the registers here,
+                * before reenabling the NMI delivery. Refer to p4_rearm()
+                * about the P4_CCCR_OVF quirk.
+                */
+               if (reset_devices) {
+                       unsigned int low, high;
+                       int i;
+
+                       for (i = 0; i < P4_CONTROLS; i++) {
+                               rdmsr(p4_controls[i], low, high);
+                               low &= ~(P4_CCCR_ENABLE | P4_CCCR_OVF);
+                               wrmsr(p4_controls[i], low, high);
+                       }
+               }
        } else {
                /* logical cpu 1 */
                perfctr_msr = MSR_P4_IQ_PERFCTR1;
@@ -499,12 +552,17 @@ static int setup_p4_watchdog(unsigned nmi_hz)
        wrmsr(evntsel_msr, evntsel, 0);
        wrmsr(cccr_msr, cccr_val, 0);
        write_watchdog_counter(perfctr_msr, "P4_IQ_COUNTER0", nmi_hz);
-       apic_write(APIC_LVTPC, APIC_DM_NMI);
-       cccr_val |= P4_CCCR_ENABLE;
-       wrmsr(cccr_msr, cccr_val, 0);
+
        wd->perfctr_msr = perfctr_msr;
        wd->evntsel_msr = evntsel_msr;
        wd->cccr_msr = cccr_msr;
+
+       /* ok, everything is initialized, announce that we're set */
+       cpu_nmi_set_wd_enabled();
+
+       apic_write(APIC_LVTPC, APIC_DM_NMI);
+       cccr_val |= P4_CCCR_ENABLE;
+       wrmsr(cccr_msr, cccr_val, 0);
        return 1;
 }
 
@@ -620,13 +678,17 @@ static int setup_intel_arch_watchdog(unsigned nmi_hz)
        wrmsr(evntsel_msr, evntsel, 0);
        nmi_hz = adjust_for_32bit_ctr(nmi_hz);
        write_watchdog_counter32(perfctr_msr, "INTEL_ARCH_PERFCTR0", nmi_hz);
-       apic_write(APIC_LVTPC, APIC_DM_NMI);
-       evntsel |= ARCH_PERFMON_EVENTSEL0_ENABLE;
-       wrmsr(evntsel_msr, evntsel, 0);
 
        wd->perfctr_msr = perfctr_msr;
        wd->evntsel_msr = evntsel_msr;
        wd->cccr_msr = 0;  /* unused */
+
+       /* ok, everything is initialized, announce that we're set */
+       cpu_nmi_set_wd_enabled();
+
+       apic_write(APIC_LVTPC, APIC_DM_NMI);
+       evntsel |= ARCH_PERFMON_EVENTSEL0_ENABLE;
+       wrmsr(evntsel_msr, evntsel, 0);
        intel_arch_wd_ops.checkbit = 1ULL << (eax.split.bit_width - 1);
        return 1;
 }
index 8e9cd6a8ec120951c4683b410572d63b0c3d0824..6a44d646599156cc5910cce8f503832688c973a5 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/smp_lock.h>
 #include <linux/major.h>
 #include <linux/fs.h>
-#include <linux/smp_lock.h>
 #include <linux/device.h>
 #include <linux/cpu.h>
 #include <linux/notifier.h>
index 15e6c6bc4a46644490cfe565c342b562cddb383d..e90a60ef10c2b641f524844e4902969cdd8235b4 100644 (file)
@@ -7,9 +7,8 @@
 
 #include <linux/errno.h>
 #include <linux/crash_dump.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
 
 /**
  * copy_oldmem_page - copy one page from "oldmem"
@@ -25,7 +24,7 @@
  * in the current kernel. We stitch up a pte, similar to kmap_atomic.
  */
 ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
-                               size_t csize, unsigned long offset, int userbuf)
+               size_t csize, unsigned long offset, int userbuf)
 {
        void  *vaddr;
 
@@ -33,14 +32,16 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
                return 0;
 
        vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
+       if (!vaddr)
+               return -ENOMEM;
 
        if (userbuf) {
-               if (copy_to_user(buf, (vaddr + offset), csize)) {
+               if (copy_to_user(buf, vaddr + offset, csize)) {
                        iounmap(vaddr);
                        return -EFAULT;
                }
        } else
-       memcpy(buf, (vaddr + offset), csize);
+               memcpy(buf, vaddr + offset, csize);
 
        iounmap(vaddr);
        return csize;
index 11c11b8ec48dd59f1494c2051433dd8f6f2a7777..2b69994fd3a800458f4d81abbebad357405eac69 100644 (file)
@@ -2,26 +2,49 @@
  * Debug Store support
  *
  * This provides a low-level interface to the hardware's Debug Store
- * feature that is used for last branch recording (LBR) and
+ * feature that is used for branch trace store (BTS) and
  * precise-event based sampling (PEBS).
  *
- * Different architectures use a different DS layout/pointer size.
- * The below functions therefore work on a void*.
+ * It manages:
+ * - per-thread and per-cpu allocation of BTS and PEBS
+ * - buffer memory allocation (optional)
+ * - buffer overflow handling
+ * - buffer access
  *
+ * It assumes:
+ * - get_task_struct on all parameter tasks
+ * - current is allowed to trace parameter tasks
  *
- * Since there is no user for PEBS, yet, only LBR (or branch
- * trace store, BTS) is supported.
  *
- *
- * Copyright (C) 2007 Intel Corporation.
- * Markus Metzger <markus.t.metzger@intel.com>, Dec 2007
+ * Copyright (C) 2007-2008 Intel Corporation.
+ * Markus Metzger <markus.t.metzger@intel.com>, 2007-2008
  */
 
+
+#ifdef CONFIG_X86_DS
+
 #include <asm/ds.h>
 
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+
+/*
+ * The configuration for a particular DS hardware implementation.
+ */
+struct ds_configuration {
+       /* the size of the DS structure in bytes */
+       unsigned char  sizeof_ds;
+       /* the size of one pointer-typed field in the DS structure in bytes;
+          this covers the first 8 fields related to buffer management. */
+       unsigned char  sizeof_field;
+       /* the size of a BTS/PEBS record in bytes */
+       unsigned char  sizeof_rec[2];
+};
+static struct ds_configuration ds_cfg;
 
 
 /*
  *   (interrupt occurs when write pointer passes interrupt pointer)
  * - value to which counter is reset following counter overflow
  *
- * On later architectures, the last branch recording hardware uses
- * 64bit pointers even in 32bit mode.
- *
- *
- * Branch Trace Store (BTS) records store information about control
- * flow changes. They at least provide the following information:
- * - source linear address
- * - destination linear address
+ * Later architectures use 64bit pointers throughout, whereas earlier
+ * architectures use 32bit pointers in 32bit mode.
  *
- * Netburst supported a predicated bit that had been dropped in later
- * architectures. We do not suppor it.
  *
+ * We compute the base address for the first 8 fields based on:
+ * - the field size stored in the DS configuration
+ * - the relative field position
+ * - an offset giving the start of the respective region
  *
- * In order to abstract from the actual DS and BTS layout, we describe
- * the access to the relevant fields.
- * Thanks to Andi Kleen for proposing this design.
+ * This offset is further used to index various arrays holding
+ * information for BTS and PEBS at the respective index.
  *
- * The implementation, however, is not as general as it might seem. In
- * order to stay somewhat simple and efficient, we assume an
- * underlying unsigned type (mostly a pointer type) and we expect the
- * field to be at least as big as that type.
+ * On later 32bit processors, we only access the lower 32bit of the
+ * 64bit pointer fields. The upper halves will be zeroed out.
  */
 
-/*
- * A special from_ip address to indicate that the BTS record is an
- * info record that needs to be interpreted or skipped.
- */
-#define BTS_ESCAPE_ADDRESS (-1)
+enum ds_field {
+       ds_buffer_base = 0,
+       ds_index,
+       ds_absolute_maximum,
+       ds_interrupt_threshold,
+};
 
-/*
- * A field access descriptor
- */
-struct access_desc {
-       unsigned char offset;
-       unsigned char size;
+enum ds_qualifier {
+       ds_bts  = 0,
+       ds_pebs
 };
 
+static inline unsigned long ds_get(const unsigned char *base,
+                                  enum ds_qualifier qual, enum ds_field field)
+{
+       base += (ds_cfg.sizeof_field * (field + (4 * qual)));
+       return *(unsigned long *)base;
+}
+
+static inline void ds_set(unsigned char *base, enum ds_qualifier qual,
+                         enum ds_field field, unsigned long value)
+{
+       base += (ds_cfg.sizeof_field * (field + (4 * qual)));
+       (*(unsigned long *)base) = value;
+}
+
+
 /*
- * The configuration for a particular DS/BTS hardware implementation.
+ * Locking is done only for allocating BTS or PEBS resources and for
+ * guarding context and buffer memory allocation.
+ *
+ * Most functions require the current task to own the ds context part
+ * they are going to access. All the locking is done when validating
+ * access to the context.
  */
-struct ds_configuration {
-       /* the DS configuration */
-       unsigned char  sizeof_ds;
-       struct access_desc bts_buffer_base;
-       struct access_desc bts_index;
-       struct access_desc bts_absolute_maximum;
-       struct access_desc bts_interrupt_threshold;
-       /* the BTS configuration */
-       unsigned char  sizeof_bts;
-       struct access_desc from_ip;
-       struct access_desc to_ip;
-       /* BTS variants used to store additional information like
-          timestamps */
-       struct access_desc info_type;
-       struct access_desc info_data;
-       unsigned long debugctl_mask;
-};
+static spinlock_t ds_lock = __SPIN_LOCK_UNLOCKED(ds_lock);
 
 /*
- * The global configuration used by the below accessor functions
+ * Validate that the current task is allowed to access the BTS/PEBS
+ * buffer of the parameter task.
+ *
+ * Returns 0, if access is granted; -Eerrno, otherwise.
  */
-static struct ds_configuration ds_cfg;
+static inline int ds_validate_access(struct ds_context *context,
+                                    enum ds_qualifier qual)
+{
+       if (!context)
+               return -EPERM;
+
+       if (context->owner[qual] == current)
+               return 0;
+
+       return -EPERM;
+}
+
 
 /*
- * Accessor functions for some DS and BTS fields using the above
- * global ptrace_bts_cfg.
+ * We either support (system-wide) per-cpu or per-thread allocation.
+ * We distinguish the two based on the task_struct pointer, where a
+ * NULL pointer indicates per-cpu allocation for the current cpu.
+ *
+ * Allocations are use-counted. As soon as resources are allocated,
+ * further allocations must be of the same type (per-cpu or
+ * per-thread). We model this by counting allocations (i.e. the number
+ * of tracers of a certain type) for one type negatively:
+ *   =0  no tracers
+ *   >0  number of per-thread tracers
+ *   <0  number of per-cpu tracers
+ *
+ * The below functions to get and put tracers and to check the
+ * allocation type require the ds_lock to be held by the caller.
+ *
+ * Tracers essentially gives the number of ds contexts for a certain
+ * type of allocation.
  */
-static inline unsigned long get_bts_buffer_base(char *base)
+static long tracers;
+
+static inline void get_tracer(struct task_struct *task)
 {
-       return *(unsigned long *)(base + ds_cfg.bts_buffer_base.offset);
+       tracers += (task ? 1 : -1);
 }
-static inline void set_bts_buffer_base(char *base, unsigned long value)
+
+static inline void put_tracer(struct task_struct *task)
 {
-       (*(unsigned long *)(base + ds_cfg.bts_buffer_base.offset)) = value;
+       tracers -= (task ? 1 : -1);
 }
-static inline unsigned long get_bts_index(char *base)
+
+static inline int check_tracer(struct task_struct *task)
 {
-       return *(unsigned long *)(base + ds_cfg.bts_index.offset);
+       return (task ? (tracers >= 0) : (tracers <= 0));
 }
-static inline void set_bts_index(char *base, unsigned long value)
+
+
+/*
+ * The DS context is either attached to a thread or to a cpu:
+ * - in the former case, the thread_struct contains a pointer to the
+ *   attached context.
+ * - in the latter case, we use a static array of per-cpu context
+ *   pointers.
+ *
+ * Contexts are use-counted. They are allocated on first access and
+ * deallocated when the last user puts the context.
+ *
+ * We distinguish between an allocating and a non-allocating get of a
+ * context:
+ * - the allocating get is used for requesting BTS/PEBS resources. It
+ *   requires the caller to hold the global ds_lock.
+ * - the non-allocating get is used for all other cases. A
+ *   non-existing context indicates an error. It acquires and releases
+ *   the ds_lock itself for obtaining the context.
+ *
+ * A context and its DS configuration are allocated and deallocated
+ * together. A context always has a DS configuration of the
+ * appropriate size.
+ */
+static DEFINE_PER_CPU(struct ds_context *, system_context);
+
+#define this_system_context per_cpu(system_context, smp_processor_id())
+
+/*
+ * Returns the pointer to the parameter task's context or to the
+ * system-wide context, if task is NULL.
+ *
+ * Increases the use count of the returned context, if not NULL.
+ */
+static inline struct ds_context *ds_get_context(struct task_struct *task)
 {
-       (*(unsigned long *)(base + ds_cfg.bts_index.offset)) = value;
+       struct ds_context *context;
+
+       spin_lock(&ds_lock);
+
+       context = (task ? task->thread.ds_ctx : this_system_context);
+       if (context)
+               context->count++;
+
+       spin_unlock(&ds_lock);
+
+       return context;
 }
-static inline unsigned long get_bts_absolute_maximum(char *base)
+
+/*
+ * Same as ds_get_context, but allocates the context and it's DS
+ * structure, if necessary; returns NULL; if out of memory.
+ *
+ * pre: requires ds_lock to be held
+ */
+static inline struct ds_context *ds_alloc_context(struct task_struct *task)
 {
-       return *(unsigned long *)(base + ds_cfg.bts_absolute_maximum.offset);
+       struct ds_context **p_context =
+               (task ? &task->thread.ds_ctx : &this_system_context);
+       struct ds_context *context = *p_context;
+
+       if (!context) {
+               context = kzalloc(sizeof(*context), GFP_KERNEL);
+
+               if (!context)
+                       return NULL;
+
+               context->ds = kzalloc(ds_cfg.sizeof_ds, GFP_KERNEL);
+               if (!context->ds) {
+                       kfree(context);
+                       return NULL;
+               }
+
+               *p_context = context;
+
+               context->this = p_context;
+               context->task = task;
+
+               if (task)
+                       set_tsk_thread_flag(task, TIF_DS_AREA_MSR);
+
+               if (!task || (task == current))
+                       wrmsr(MSR_IA32_DS_AREA, (unsigned long)context->ds, 0);
+
+               get_tracer(task);
+       }
+
+       context->count++;
+
+       return context;
 }
-static inline void set_bts_absolute_maximum(char *base, unsigned long value)
+
+/*
+ * Decreases the use count of the parameter context, if not NULL.
+ * Deallocates the context, if the use count reaches zero.
+ */
+static inline void ds_put_context(struct ds_context *context)
 {
-       (*(unsigned long *)(base + ds_cfg.bts_absolute_maximum.offset)) = value;
+       if (!context)
+               return;
+
+       spin_lock(&ds_lock);
+
+       if (--context->count)
+               goto out;
+
+       *(context->this) = NULL;
+
+       if (context->task)
+               clear_tsk_thread_flag(context->task, TIF_DS_AREA_MSR);
+
+       if (!context->task || (context->task == current))
+               wrmsrl(MSR_IA32_DS_AREA, 0);
+
+       put_tracer(context->task);
+
+       /* free any leftover buffers from tracers that did not
+        * deallocate them properly. */
+       kfree(context->buffer[ds_bts]);
+       kfree(context->buffer[ds_pebs]);
+       kfree(context->ds);
+       kfree(context);
+ out:
+       spin_unlock(&ds_lock);
 }
-static inline unsigned long get_bts_interrupt_threshold(char *base)
+
+
+/*
+ * Handle a buffer overflow
+ *
+ * task: the task whose buffers are overflowing;
+ *       NULL for a buffer overflow on the current cpu
+ * context: the ds context
+ * qual: the buffer type
+ */
+static void ds_overflow(struct task_struct *task, struct ds_context *context,
+                       enum ds_qualifier qual)
 {
-       return *(unsigned long *)(base + ds_cfg.bts_interrupt_threshold.offset);
+       if (!context)
+               return;
+
+       if (context->callback[qual])
+               (*context->callback[qual])(task);
+
+       /* todo: do some more overflow handling */
 }
-static inline void set_bts_interrupt_threshold(char *base, unsigned long value)
+
+
+/*
+ * Allocate a non-pageable buffer of the parameter size.
+ * Checks the memory and the locked memory rlimit.
+ *
+ * Returns the buffer, if successful;
+ *         NULL, if out of memory or rlimit exceeded.
+ *
+ * size: the requested buffer size in bytes
+ * pages (out): if not NULL, contains the number of pages reserved
+ */
+static inline void *ds_allocate_buffer(size_t size, unsigned int *pages)
 {
-       (*(unsigned long *)(base + ds_cfg.bts_interrupt_threshold.offset)) = value;
+       unsigned long rlim, vm, pgsz;
+       void *buffer;
+
+       pgsz = PAGE_ALIGN(size) >> PAGE_SHIFT;
+
+       rlim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
+       vm   = current->mm->total_vm  + pgsz;
+       if (rlim < vm)
+               return NULL;
+
+       rlim = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
+       vm   = current->mm->locked_vm  + pgsz;
+       if (rlim < vm)
+               return NULL;
+
+       buffer = kzalloc(size, GFP_KERNEL);
+       if (!buffer)
+               return NULL;
+
+       current->mm->total_vm  += pgsz;
+       current->mm->locked_vm += pgsz;
+
+       if (pages)
+               *pages = pgsz;
+
+       return buffer;
 }
-static inline unsigned long get_from_ip(char *base)
+
+static int ds_request(struct task_struct *task, void *base, size_t size,
+                     ds_ovfl_callback_t ovfl, enum ds_qualifier qual)
 {
-       return *(unsigned long *)(base + ds_cfg.from_ip.offset);
+       struct ds_context *context;
+       unsigned long buffer, adj;
+       const unsigned long alignment = (1 << 3);
+       int error = 0;
+
+       if (!ds_cfg.sizeof_ds)
+               return -EOPNOTSUPP;
+
+       /* we require some space to do alignment adjustments below */
+       if (size < (alignment + ds_cfg.sizeof_rec[qual]))
+               return -EINVAL;
+
+       /* buffer overflow notification is not yet implemented */
+       if (ovfl)
+               return -EOPNOTSUPP;
+
+
+       spin_lock(&ds_lock);
+
+       if (!check_tracer(task))
+               return -EPERM;
+
+       error = -ENOMEM;
+       context = ds_alloc_context(task);
+       if (!context)
+               goto out_unlock;
+
+       error = -EALREADY;
+       if (context->owner[qual] == current)
+               goto out_unlock;
+       error = -EPERM;
+       if (context->owner[qual] != NULL)
+               goto out_unlock;
+       context->owner[qual] = current;
+
+       spin_unlock(&ds_lock);
+
+
+       error = -ENOMEM;
+       if (!base) {
+               base = ds_allocate_buffer(size, &context->pages[qual]);
+               if (!base)
+                       goto out_release;
+
+               context->buffer[qual]   = base;
+       }
+       error = 0;
+
+       context->callback[qual] = ovfl;
+
+       /* adjust the buffer address and size to meet alignment
+        * constraints:
+        * - buffer is double-word aligned
+        * - size is multiple of record size
+        *
+        * We checked the size at the very beginning; we have enough
+        * space to do the adjustment.
+        */
+       buffer = (unsigned long)base;
+
+       adj = ALIGN(buffer, alignment) - buffer;
+       buffer += adj;
+       size   -= adj;
+
+       size /= ds_cfg.sizeof_rec[qual];
+       size *= ds_cfg.sizeof_rec[qual];
+
+       ds_set(context->ds, qual, ds_buffer_base, buffer);
+       ds_set(context->ds, qual, ds_index, buffer);
+       ds_set(context->ds, qual, ds_absolute_maximum, buffer + size);
+
+       if (ovfl) {
+               /* todo: select a suitable interrupt threshold */
+       } else
+               ds_set(context->ds, qual,
+                      ds_interrupt_threshold, buffer + size + 1);
+
+       /* we keep the context until ds_release */
+       return error;
+
+ out_release:
+       context->owner[qual] = NULL;
+       ds_put_context(context);
+       return error;
+
+ out_unlock:
+       spin_unlock(&ds_lock);
+       ds_put_context(context);
+       return error;
 }
-static inline void set_from_ip(char *base, unsigned long value)
+
+int ds_request_bts(struct task_struct *task, void *base, size_t size,
+                  ds_ovfl_callback_t ovfl)
 {
-       (*(unsigned long *)(base + ds_cfg.from_ip.offset)) = value;
+       return ds_request(task, base, size, ovfl, ds_bts);
 }
-static inline unsigned long get_to_ip(char *base)
+
+int ds_request_pebs(struct task_struct *task, void *base, size_t size,
+                   ds_ovfl_callback_t ovfl)
 {
-       return *(unsigned long *)(base + ds_cfg.to_ip.offset);
+       return ds_request(task, base, size, ovfl, ds_pebs);
 }
-static inline void set_to_ip(char *base, unsigned long value)
+
+static int ds_release(struct task_struct *task, enum ds_qualifier qual)
 {
-       (*(unsigned long *)(base + ds_cfg.to_ip.offset)) = value;
+       struct ds_context *context;
+       int error;
+
+       context = ds_get_context(task);
+       error = ds_validate_access(context, qual);
+       if (error < 0)
+               goto out;
+
+       kfree(context->buffer[qual]);
+       context->buffer[qual] = NULL;
+
+       current->mm->total_vm  -= context->pages[qual];
+       current->mm->locked_vm -= context->pages[qual];
+       context->pages[qual] = 0;
+       context->owner[qual] = NULL;
+
+       /*
+        * we put the context twice:
+        *   once for the ds_get_context
+        *   once for the corresponding ds_request
+        */
+       ds_put_context(context);
+ out:
+       ds_put_context(context);
+       return error;
 }
-static inline unsigned char get_info_type(char *base)
+
+int ds_release_bts(struct task_struct *task)
 {
-       return *(unsigned char *)(base + ds_cfg.info_type.offset);
+       return ds_release(task, ds_bts);
 }
-static inline void set_info_type(char *base, unsigned char value)
+
+int ds_release_pebs(struct task_struct *task)
 {
-       (*(unsigned char *)(base + ds_cfg.info_type.offset)) = value;
+       return ds_release(task, ds_pebs);
 }
-static inline unsigned long get_info_data(char *base)
+
+static int ds_get_index(struct task_struct *task, size_t *pos,
+                       enum ds_qualifier qual)
 {
-       return *(unsigned long *)(base + ds_cfg.info_data.offset);
+       struct ds_context *context;
+       unsigned long base, index;
+       int error;
+
+       context = ds_get_context(task);
+       error = ds_validate_access(context, qual);
+       if (error < 0)
+               goto out;
+
+       base  = ds_get(context->ds, qual, ds_buffer_base);
+       index = ds_get(context->ds, qual, ds_index);
+
+       error = ((index - base) / ds_cfg.sizeof_rec[qual]);
+       if (pos)
+               *pos = error;
+ out:
+       ds_put_context(context);
+       return error;
 }
-static inline void set_info_data(char *base, unsigned long value)
+
+int ds_get_bts_index(struct task_struct *task, size_t *pos)
 {
-       (*(unsigned long *)(base + ds_cfg.info_data.offset)) = value;
+       return ds_get_index(task, pos, ds_bts);
 }
 
+int ds_get_pebs_index(struct task_struct *task, size_t *pos)
+{
+       return ds_get_index(task, pos, ds_pebs);
+}
 
-int ds_allocate(void **dsp, size_t bts_size_in_bytes)
+static int ds_get_end(struct task_struct *task, size_t *pos,
+                     enum ds_qualifier qual)
 {
-       size_t bts_size_in_records;
-       unsigned long bts;
-       void *ds;
+       struct ds_context *context;
+       unsigned long base, end;
+       int error;
+
+       context = ds_get_context(task);
+       error = ds_validate_access(context, qual);
+       if (error < 0)
+               goto out;
+
+       base = ds_get(context->ds, qual, ds_buffer_base);
+       end  = ds_get(context->ds, qual, ds_absolute_maximum);
+
+       error = ((end - base) / ds_cfg.sizeof_rec[qual]);
+       if (pos)
+               *pos = error;
+ out:
+       ds_put_context(context);
+       return error;
+}
 
-       if (!ds_cfg.sizeof_ds || !ds_cfg.sizeof_bts)
-               return -EOPNOTSUPP;
+int ds_get_bts_end(struct task_struct *task, size_t *pos)
+{
+       return ds_get_end(task, pos, ds_bts);
+}
 
-       if (bts_size_in_bytes < 0)
-               return -EINVAL;
+int ds_get_pebs_end(struct task_struct *task, size_t *pos)
+{
+       return ds_get_end(task, pos, ds_pebs);
+}
 
-       bts_size_in_records =
-               bts_size_in_bytes / ds_cfg.sizeof_bts;
-       bts_size_in_bytes =
-               bts_size_in_records * ds_cfg.sizeof_bts;
+static int ds_access(struct task_struct *task, size_t index,
+                    const void **record, enum ds_qualifier qual)
+{
+       struct ds_context *context;
+       unsigned long base, idx;
+       int error;
 
-       if (bts_size_in_bytes <= 0)
+       if (!record)
                return -EINVAL;
 
-       bts = (unsigned long)kzalloc(bts_size_in_bytes, GFP_KERNEL);
-
-       if (!bts)
-               return -ENOMEM;
+       context = ds_get_context(task);
+       error = ds_validate_access(context, qual);
+       if (error < 0)
+               goto out;
 
-       ds = kzalloc(ds_cfg.sizeof_ds, GFP_KERNEL);
+       base = ds_get(context->ds, qual, ds_buffer_base);
+       idx = base + (index * ds_cfg.sizeof_rec[qual]);
 
-       if (!ds) {
-               kfree((void *)bts);
-               return -ENOMEM;
-       }
-
-       set_bts_buffer_base(ds, bts);
-       set_bts_index(ds, bts);
-       set_bts_absolute_maximum(ds, bts + bts_size_in_bytes);
-       set_bts_interrupt_threshold(ds, bts + bts_size_in_bytes + 1);
+       error = -EINVAL;
+       if (idx > ds_get(context->ds, qual, ds_absolute_maximum))
+               goto out;
 
-       *dsp = ds;
-       return 0;
+       *record = (const void *)idx;
+       error = ds_cfg.sizeof_rec[qual];
+ out:
+       ds_put_context(context);
+       return error;
 }
 
-int ds_free(void **dsp)
+int ds_access_bts(struct task_struct *task, size_t index, const void **record)
 {
-       if (*dsp) {
-               kfree((void *)get_bts_buffer_base(*dsp));
-               kfree(*dsp);
-               *dsp = NULL;
-       }
-       return 0;
+       return ds_access(task, index, record, ds_bts);
 }
 
-int ds_get_bts_size(void *ds)
+int ds_access_pebs(struct task_struct *task, size_t index, const void **record)
 {
-       int size_in_bytes;
-
-       if (!ds_cfg.sizeof_ds || !ds_cfg.sizeof_bts)
-               return -EOPNOTSUPP;
-
-       if (!ds)
-               return 0;
-
-       size_in_bytes =
-               get_bts_absolute_maximum(ds) -
-               get_bts_buffer_base(ds);
-       return size_in_bytes;
+       return ds_access(task, index, record, ds_pebs);
 }
 
-int ds_get_bts_end(void *ds)
+static int ds_write(struct task_struct *task, const void *record, size_t size,
+                   enum ds_qualifier qual, int force)
 {
-       int size_in_bytes = ds_get_bts_size(ds);
-
-       if (size_in_bytes <= 0)
-               return size_in_bytes;
+       struct ds_context *context;
+       int error;
 
-       return size_in_bytes / ds_cfg.sizeof_bts;
-}
+       if (!record)
+               return -EINVAL;
 
-int ds_get_bts_index(void *ds)
-{
-       int index_offset_in_bytes;
+       error = -EPERM;
+       context = ds_get_context(task);
+       if (!context)
+               goto out;
 
-       if (!ds_cfg.sizeof_ds || !ds_cfg.sizeof_bts)
-               return -EOPNOTSUPP;
+       if (!force) {
+               error = ds_validate_access(context, qual);
+               if (error < 0)
+                       goto out;
+       }
 
-       index_offset_in_bytes =
-               get_bts_index(ds) -
-               get_bts_buffer_base(ds);
+       error = 0;
+       while (size) {
+               unsigned long base, index, end, write_end, int_th;
+               unsigned long write_size, adj_write_size;
+
+               /*
+                * write as much as possible without producing an
+                * overflow interrupt.
+                *
+                * interrupt_threshold must either be
+                * - bigger than absolute_maximum or
+                * - point to a record between buffer_base and absolute_maximum
+                *
+                * index points to a valid record.
+                */
+               base   = ds_get(context->ds, qual, ds_buffer_base);
+               index  = ds_get(context->ds, qual, ds_index);
+               end    = ds_get(context->ds, qual, ds_absolute_maximum);
+               int_th = ds_get(context->ds, qual, ds_interrupt_threshold);
+
+               write_end = min(end, int_th);
+
+               /* if we are already beyond the interrupt threshold,
+                * we fill the entire buffer */
+               if (write_end <= index)
+                       write_end = end;
+
+               if (write_end <= index)
+                       goto out;
+
+               write_size = min((unsigned long) size, write_end - index);
+               memcpy((void *)index, record, write_size);
+
+               record = (const char *)record + write_size;
+               size  -= write_size;
+               error += write_size;
+
+               adj_write_size = write_size / ds_cfg.sizeof_rec[qual];
+               adj_write_size *= ds_cfg.sizeof_rec[qual];
+
+               /* zero out trailing bytes */
+               memset((char *)index + write_size, 0,
+                      adj_write_size - write_size);
+               index += adj_write_size;
+
+               if (index >= end)
+                       index = base;
+               ds_set(context->ds, qual, ds_index, index);
+
+               if (index >= int_th)
+                       ds_overflow(task, context, qual);
+       }
 
-       return index_offset_in_bytes / ds_cfg.sizeof_bts;
+ out:
+       ds_put_context(context);
+       return error;
 }
 
-int ds_set_overflow(void *ds, int method)
+int ds_write_bts(struct task_struct *task, const void *record, size_t size)
 {
-       switch (method) {
-       case DS_O_SIGNAL:
-               return -EOPNOTSUPP;
-       case DS_O_WRAP:
-               return 0;
-       default:
-               return -EINVAL;
-       }
+       return ds_write(task, record, size, ds_bts, /* force = */ 0);
 }
 
-int ds_get_overflow(void *ds)
+int ds_write_pebs(struct task_struct *task, const void *record, size_t size)
 {
-       return DS_O_WRAP;
+       return ds_write(task, record, size, ds_pebs, /* force = */ 0);
 }
 
-int ds_clear(void *ds)
+int ds_unchecked_write_bts(struct task_struct *task,
+                          const void *record, size_t size)
 {
-       int bts_size = ds_get_bts_size(ds);
-       unsigned long bts_base;
-
-       if (bts_size <= 0)
-               return bts_size;
-
-       bts_base = get_bts_buffer_base(ds);
-       memset((void *)bts_base, 0, bts_size);
-
-       set_bts_index(ds, bts_base);
-       return 0;
+       return ds_write(task, record, size, ds_bts, /* force = */ 1);
 }
 
-int ds_read_bts(void *ds, int index, struct bts_struct *out)
+int ds_unchecked_write_pebs(struct task_struct *task,
+                           const void *record, size_t size)
 {
-       void *bts;
+       return ds_write(task, record, size, ds_pebs, /* force = */ 1);
+}
 
-       if (!ds_cfg.sizeof_ds || !ds_cfg.sizeof_bts)
-               return -EOPNOTSUPP;
+static int ds_reset_or_clear(struct task_struct *task,
+                            enum ds_qualifier qual, int clear)
+{
+       struct ds_context *context;
+       unsigned long base, end;
+       int error;
 
-       if (index < 0)
-               return -EINVAL;
+       context = ds_get_context(task);
+       error = ds_validate_access(context, qual);
+       if (error < 0)
+               goto out;
 
-       if (index >= ds_get_bts_size(ds))
-               return -EINVAL;
+       base = ds_get(context->ds, qual, ds_buffer_base);
+       end  = ds_get(context->ds, qual, ds_absolute_maximum);
 
-       bts = (void *)(get_bts_buffer_base(ds) + (index * ds_cfg.sizeof_bts));
+       if (clear)
+               memset((void *)base, 0, end - base);
 
-       memset(out, 0, sizeof(*out));
-       if (get_from_ip(bts) == BTS_ESCAPE_ADDRESS) {
-               out->qualifier       = get_info_type(bts);
-               out->variant.jiffies = get_info_data(bts);
-       } else {
-               out->qualifier = BTS_BRANCH;
-               out->variant.lbr.from_ip = get_from_ip(bts);
-               out->variant.lbr.to_ip   = get_to_ip(bts);
-       }
+       ds_set(context->ds, qual, ds_index, base);
 
-       return sizeof(*out);;
+       error = 0;
+ out:
+       ds_put_context(context);
+       return error;
 }
 
-int ds_write_bts(void *ds, const struct bts_struct *in)
+int ds_reset_bts(struct task_struct *task)
 {
-       unsigned long bts;
-
-       if (!ds_cfg.sizeof_ds || !ds_cfg.sizeof_bts)
-               return -EOPNOTSUPP;
-
-       if (ds_get_bts_size(ds) <= 0)
-               return -ENXIO;
+       return ds_reset_or_clear(task, ds_bts, /* clear = */ 0);
+}
 
-       bts = get_bts_index(ds);
+int ds_reset_pebs(struct task_struct *task)
+{
+       return ds_reset_or_clear(task, ds_pebs, /* clear = */ 0);
+}
 
-       memset((void *)bts, 0, ds_cfg.sizeof_bts);
-       switch (in->qualifier) {
-       case BTS_INVALID:
-               break;
+int ds_clear_bts(struct task_struct *task)
+{
+       return ds_reset_or_clear(task, ds_bts, /* clear = */ 1);
+}
 
-       case BTS_BRANCH:
-               set_from_ip((void *)bts, in->variant.lbr.from_ip);
-               set_to_ip((void *)bts, in->variant.lbr.to_ip);
-               break;
+int ds_clear_pebs(struct task_struct *task)
+{
+       return ds_reset_or_clear(task, ds_pebs, /* clear = */ 1);
+}
 
-       case BTS_TASK_ARRIVES:
-       case BTS_TASK_DEPARTS:
-               set_from_ip((void *)bts, BTS_ESCAPE_ADDRESS);
-               set_info_type((void *)bts, in->qualifier);
-               set_info_data((void *)bts, in->variant.jiffies);
-               break;
+int ds_get_pebs_reset(struct task_struct *task, u64 *value)
+{
+       struct ds_context *context;
+       int error;
 
-       default:
+       if (!value)
                return -EINVAL;
-       }
 
-       bts = bts + ds_cfg.sizeof_bts;
-       if (bts >= get_bts_absolute_maximum(ds))
-               bts = get_bts_buffer_base(ds);
-       set_bts_index(ds, bts);
+       context = ds_get_context(task);
+       error = ds_validate_access(context, ds_pebs);
+       if (error < 0)
+               goto out;
 
-       return ds_cfg.sizeof_bts;
+       *value = *(u64 *)(context->ds + (ds_cfg.sizeof_field * 8));
+
+       error = 0;
+ out:
+       ds_put_context(context);
+       return error;
 }
 
-unsigned long ds_debugctl_mask(void)
+int ds_set_pebs_reset(struct task_struct *task, u64 value)
 {
-       return ds_cfg.debugctl_mask;
-}
+       struct ds_context *context;
+       int error;
 
-#ifdef __i386__
-static const struct ds_configuration ds_cfg_netburst = {
-       .sizeof_ds = 9 * 4,
-       .bts_buffer_base = { 0, 4 },
-       .bts_index = { 4, 4 },
-       .bts_absolute_maximum = { 8, 4 },
-       .bts_interrupt_threshold = { 12, 4 },
-       .sizeof_bts = 3 * 4,
-       .from_ip = { 0, 4 },
-       .to_ip = { 4, 4 },
-       .info_type = { 4, 1 },
-       .info_data = { 8, 4 },
-       .debugctl_mask = (1<<2)|(1<<3)
-};
+       context = ds_get_context(task);
+       error = ds_validate_access(context, ds_pebs);
+       if (error < 0)
+               goto out;
 
-static const struct ds_configuration ds_cfg_pentium_m = {
-       .sizeof_ds = 9 * 4,
-       .bts_buffer_base = { 0, 4 },
-       .bts_index = { 4, 4 },
-       .bts_absolute_maximum = { 8, 4 },
-       .bts_interrupt_threshold = { 12, 4 },
-       .sizeof_bts = 3 * 4,
-       .from_ip = { 0, 4 },
-       .to_ip = { 4, 4 },
-       .info_type = { 4, 1 },
-       .info_data = { 8, 4 },
-       .debugctl_mask = (1<<6)|(1<<7)
+       *(u64 *)(context->ds + (ds_cfg.sizeof_field * 8)) = value;
+
+       error = 0;
+ out:
+       ds_put_context(context);
+       return error;
+}
+
+static const struct ds_configuration ds_cfg_var = {
+       .sizeof_ds    = sizeof(long) * 12,
+       .sizeof_field = sizeof(long),
+       .sizeof_rec[ds_bts]   = sizeof(long) * 3,
+       .sizeof_rec[ds_pebs]  = sizeof(long) * 10
 };
-#endif /* _i386_ */
-
-static const struct ds_configuration ds_cfg_core2 = {
-       .sizeof_ds = 9 * 8,
-       .bts_buffer_base = { 0, 8 },
-       .bts_index = { 8, 8 },
-       .bts_absolute_maximum = { 16, 8 },
-       .bts_interrupt_threshold = { 24, 8 },
-       .sizeof_bts = 3 * 8,
-       .from_ip = { 0, 8 },
-       .to_ip = { 8, 8 },
-       .info_type = { 8, 1 },
-       .info_data = { 16, 8 },
-       .debugctl_mask = (1<<6)|(1<<7)|(1<<9)
+static const struct ds_configuration ds_cfg_64 = {
+       .sizeof_ds    = 8 * 12,
+       .sizeof_field = 8,
+       .sizeof_rec[ds_bts]   = 8 * 3,
+       .sizeof_rec[ds_pebs]  = 8 * 10
 };
 
 static inline void
@@ -429,14 +821,13 @@ void __cpuinit ds_init_intel(struct cpuinfo_x86 *c)
        switch (c->x86) {
        case 0x6:
                switch (c->x86_model) {
-#ifdef __i386__
                case 0xD:
                case 0xE: /* Pentium M */
-                       ds_configure(&ds_cfg_pentium_m);
+                       ds_configure(&ds_cfg_var);
                        break;
-#endif /* _i386_ */
                case 0xF: /* Core2 */
-                       ds_configure(&ds_cfg_core2);
+               case 0x1C: /* Atom */
+                       ds_configure(&ds_cfg_64);
                        break;
                default:
                        /* sorry, don't know about them */
@@ -445,13 +836,11 @@ void __cpuinit ds_init_intel(struct cpuinfo_x86 *c)
                break;
        case 0xF:
                switch (c->x86_model) {
-#ifdef __i386__
                case 0x0:
                case 0x1:
                case 0x2: /* Netburst */
-                       ds_configure(&ds_cfg_netburst);
+                       ds_configure(&ds_cfg_var);
                        break;
-#endif /* _i386_ */
                default:
                        /* sorry, don't know about them */
                        break;
@@ -462,3 +851,14 @@ void __cpuinit ds_init_intel(struct cpuinfo_x86 *c)
                break;
        }
 }
+
+void ds_free(struct ds_context *context)
+{
+       /* This is called when the task owning the parameter context
+        * is dying. There should not be any user of that context left
+        * to disturb us, anymore. */
+       unsigned long leftovers = context->count;
+       while (leftovers--)
+               ds_put_context(context);
+}
+#endif /* CONFIG_X86_DS */
index 06cc8d4254b180f622a33c879bca97f2c05b1643..945a31cdd81f5493d0de00bf39214f0df371b976 100644 (file)
@@ -414,9 +414,11 @@ void __init efi_init(void)
        if (memmap.map == NULL)
                printk(KERN_ERR "Could not map the EFI memory map!\n");
        memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size);
+
        if (memmap.desc_size != sizeof(efi_memory_desc_t))
-               printk(KERN_WARNING "Kernel-defined memdesc"
-                      "doesn't match the one from EFI!\n");
+               printk(KERN_WARNING
+                 "Kernel-defined memdesc doesn't match the one from EFI!\n");
+
        if (add_efi_memmap)
                do_add_efi_memmap();
 
index 89434d439605484b48a7b26ba31c55e82c9821c5..cf3a0b2d00599adb2a79fefa991c0d8223059fba 100644 (file)
@@ -275,9 +275,9 @@ ENTRY(native_usergs_sysret64)
 ENTRY(ret_from_fork)
        CFI_DEFAULT_STACK
        push kernel_eflags(%rip)
-       CFI_ADJUST_CFA_OFFSET 4
+       CFI_ADJUST_CFA_OFFSET 8
        popf                            # reset kernel eflags
-       CFI_ADJUST_CFA_OFFSET -4
+       CFI_ADJUST_CFA_OFFSET -8
        call schedule_tail
        GET_THREAD_INFO(%rcx)
        testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%rcx)
index 9bfc4d72fb2e26b757ffad4bffd8b0de7a45de39..d16084f90649181e6e944e104118f7ec5de6a0e3 100644 (file)
@@ -108,12 +108,11 @@ void __init x86_64_start_kernel(char * real_mode_data)
        }
        load_idt((const struct desc_ptr *)&idt_descr);
 
-       early_printk("Kernel alive\n");
+       if (console_loglevel == 10)
+               early_printk("Kernel alive\n");
 
        x86_64_init_pda();
 
-       early_printk("Kernel really alive\n");
-
        x86_64_start_reservations(real_mode_data);
 }
 
index 50e5e4a31c8500e94b277378b2d3860d673fc225..19191430274496e8d04f4bd4e165f852e6753560 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/slab.h>
 #include <linux/thread_info.h>
 #include <linux/syscalls.h>
+#include <asm/syscalls.h>
 
 /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
 static void set_bitmap(unsigned long *bitmap, unsigned int base,
index 3f7537b669d312e08a6d92e92787feb0ae903549..f1c688e46f35a8443e031b0e8dd572800a86c097 100644 (file)
@@ -20,6 +20,8 @@
 
 #ifdef CONFIG_X86_32
 #include <mach_apic.h>
+#include <mach_ipi.h>
+
 /*
  * the following functions deal with sending IPIs between CPUs.
  *
@@ -147,7 +149,6 @@ void send_IPI_mask_sequence(cpumask_t mask, int vector)
 }
 
 /* must come after the send_IPI functions above for inlining */
-#include <mach_ipi.h>
 static int convert_apicid_to_cpu(int apic_id)
 {
        int i;
index 1cf8c1fcc0889c5a066ddb2b7e150ece69dc1729..b71e02d42f4fd288a21a51f256c422b6d4d74d83 100644 (file)
@@ -325,7 +325,7 @@ skip:
                for_each_online_cpu(j)
                        seq_printf(p, "%10u ",
                                per_cpu(irq_stat,j).irq_call_count);
-               seq_printf(p, "  function call interrupts\n");
+               seq_printf(p, "  Function call interrupts\n");
                seq_printf(p, "TLB: ");
                for_each_online_cpu(j)
                        seq_printf(p, "%10u ",
index 1f78b238d8d2cc8778520e048fe69d36a97209b2..f065fe9071b9f65dcaf1d519c0063065c43cce62 100644 (file)
@@ -129,7 +129,7 @@ skip:
                seq_printf(p, "CAL: ");
                for_each_online_cpu(j)
                        seq_printf(p, "%10u ", cpu_pda(j)->irq_call_count);
-               seq_printf(p, "  function call interrupts\n");
+               seq_printf(p, "  Function call interrupts\n");
                seq_printf(p, "TLB: ");
                for_each_online_cpu(j)
                        seq_printf(p, "%10u ", cpu_pda(j)->irq_tlb_count);
index 8b7a3cf37d2b8192cbe1a1fe68ff93740dd0d59f..478bca986eca0d5213f3fe992cdb409db3670ce7 100644 (file)
@@ -178,7 +178,7 @@ static void kvm_flush_tlb(void)
        kvm_deferred_mmu_op(&ftlb, sizeof ftlb);
 }
 
-static void kvm_release_pt(u32 pfn)
+static void kvm_release_pt(unsigned long pfn)
 {
        struct kvm_mmu_op_release_pt rpt = {
                .header.op = KVM_MMU_OP_RELEASE_PT,
index b68e21f06f4f84615baf2fbc47179fd437bea321..0ed5f939b9056330cb0eb5eaefe564f405b4a14a 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/ldt.h>
 #include <asm/desc.h>
 #include <asm/mmu_context.h>
+#include <asm/syscalls.h>
 
 #ifdef CONFIG_SMP
 static void flush_ldt(void *current_mm)
index abb78a2cc4ad5d1a8e43fcf1430dd6245ac57f42..2c97f07f1c2cb76a705e4e421c018837588f1b6c 100644 (file)
@@ -299,6 +299,15 @@ void acpi_nmi_disable(void)
                on_each_cpu(__acpi_nmi_disable, NULL, 1);
 }
 
+/*
+ * This function is called as soon the LAPIC NMI watchdog driver has everything
+ * in place and it's ready to check if the NMIs belong to the NMI watchdog
+ */
+void cpu_nmi_set_wd_enabled(void)
+{
+       __get_cpu_var(wd_enabled) = 1;
+}
+
 void setup_apic_nmi_watchdog(void *unused)
 {
        if (__get_cpu_var(wd_enabled))
@@ -311,8 +320,6 @@ void setup_apic_nmi_watchdog(void *unused)
 
        switch (nmi_watchdog) {
        case NMI_LOCAL_APIC:
-                /* enable it before to avoid race with handler */
-               __get_cpu_var(wd_enabled) = 1;
                if (lapic_watchdog_init(nmi_hz) < 0) {
                        __get_cpu_var(wd_enabled) = 0;
                        return;
index 3e6672274807f414ae243e924495c8e79ce9c983..7a13fac63a1f11ccd8cfe2cf72160117a0477cd2 100644 (file)
@@ -190,12 +190,12 @@ EXPORT_SYMBOL_GPL(olpc_ec_cmd);
 static void __init platform_detect(void)
 {
        size_t propsize;
-       u32 rev;
+       __be32 rev;
 
        if (ofw("getprop", 4, 1, NULL, "board-revision-int", &rev, 4,
                        &propsize) || propsize != 4) {
                printk(KERN_ERR "ofw: getprop call failed!\n");
-               rev = 0;
+               rev = cpu_to_be32(0);
        }
        olpc_platform_info.boardrev = be32_to_cpu(rev);
 }
@@ -203,7 +203,7 @@ static void __init platform_detect(void)
 static void __init platform_detect(void)
 {
        /* stopgap until OFW support is added to the kernel */
-       olpc_platform_info.boardrev = be32_to_cpu(0xc2);
+       olpc_platform_info.boardrev = 0xc2;
 }
 #endif
 
index 300da17e61cbef997d527031a49bb1e81addf897..e2f43768723a57452b15200f9f0f209e4d6622f6 100644 (file)
@@ -330,6 +330,7 @@ struct pv_cpu_ops pv_cpu_ops = {
 #endif
        .wbinvd = native_wbinvd,
        .read_msr = native_read_msr_safe,
+       .read_msr_amd = native_read_msr_amd_safe,
        .write_msr = native_write_msr_safe,
        .read_tsc = native_read_tsc,
        .read_pmc = native_read_pmc,
index 58262218781bd3582b1b99f7d42986170e49e23c..9fe644f4861d4f675206ce16f2c8f7c799a6aae5 100644 (file)
@@ -23,7 +23,7 @@ unsigned native_patch(u8 type, u16 clobbers, void *ibuf,
                        start = start_##ops##_##x;              \
                        end = end_##ops##_##x;                  \
                        goto patch_site
-       switch(type) {
+       switch (type) {
                PATCH_SITE(pv_irq_ops, irq_disable);
                PATCH_SITE(pv_irq_ops, irq_enable);
                PATCH_SITE(pv_irq_ops, restore_fl);
index 87d4d6964ec2b9ecb5d83ad01c081589218dc303..f704cb51ff82b9e04b14853c88096960f4cdc245 100644 (file)
@@ -82,7 +82,7 @@ void __init dma32_reserve_bootmem(void)
         * using 512M as goal
         */
        align = 64ULL<<20;
-       size = round_up(dma32_bootmem_size, align);
+       size = roundup(dma32_bootmem_size, align);
        dma32_bootmem_ptr = __alloc_bootmem_nopanic(size, align,
                                 512ULL<<20);
        if (dma32_bootmem_ptr)
index be33a5442d8205f958a0eb2ed5121b020b3ff32b..1a895a58253468e0cbba97b9aba7fb6d8d2fff8a 100644 (file)
@@ -82,7 +82,8 @@ AGPEXTERN __u32 *agp_gatt_table;
 static unsigned long next_bit;  /* protected by iommu_bitmap_lock */
 static int need_flush;         /* global flush state. set for each gart wrap */
 
-static unsigned long alloc_iommu(struct device *dev, int size)
+static unsigned long alloc_iommu(struct device *dev, int size,
+                                unsigned long align_mask)
 {
        unsigned long offset, flags;
        unsigned long boundary_size;
@@ -90,16 +91,17 @@ static unsigned long alloc_iommu(struct device *dev, int size)
 
        base_index = ALIGN(iommu_bus_base & dma_get_seg_boundary(dev),
                           PAGE_SIZE) >> PAGE_SHIFT;
-       boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1,
+       boundary_size = ALIGN((unsigned long long)dma_get_seg_boundary(dev) + 1,
                              PAGE_SIZE) >> PAGE_SHIFT;
 
        spin_lock_irqsave(&iommu_bitmap_lock, flags);
        offset = iommu_area_alloc(iommu_gart_bitmap, iommu_pages, next_bit,
-                                 size, base_index, boundary_size, 0);
+                                 size, base_index, boundary_size, align_mask);
        if (offset == -1) {
                need_flush = 1;
                offset = iommu_area_alloc(iommu_gart_bitmap, iommu_pages, 0,
-                                         size, base_index, boundary_size, 0);
+                                         size, base_index, boundary_size,
+                                         align_mask);
        }
        if (offset != -1) {
                next_bit = offset+size;
@@ -236,10 +238,10 @@ nonforced_iommu(struct device *dev, unsigned long addr, size_t size)
  * Caller needs to check if the iommu is needed and flush.
  */
 static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem,
-                               size_t size, int dir)
+                               size_t size, int dir, unsigned long align_mask)
 {
        unsigned long npages = iommu_num_pages(phys_mem, size);
-       unsigned long iommu_page = alloc_iommu(dev, npages);
+       unsigned long iommu_page = alloc_iommu(dev, npages, align_mask);
        int i;
 
        if (iommu_page == -1) {
@@ -262,7 +264,11 @@ static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem,
 static dma_addr_t
 gart_map_simple(struct device *dev, phys_addr_t paddr, size_t size, int dir)
 {
-       dma_addr_t map = dma_map_area(dev, paddr, size, dir);
+       dma_addr_t map;
+       unsigned long align_mask;
+
+       align_mask = (1UL << get_order(size)) - 1;
+       map = dma_map_area(dev, paddr, size, dir, align_mask);
 
        flush_gart();
 
@@ -281,7 +287,8 @@ gart_map_single(struct device *dev, phys_addr_t paddr, size_t size, int dir)
        if (!need_iommu(dev, paddr, size))
                return paddr;
 
-       bus = gart_map_simple(dev, paddr, size, dir);
+       bus = dma_map_area(dev, paddr, size, dir, 0);
+       flush_gart();
 
        return bus;
 }
@@ -340,7 +347,7 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
                unsigned long addr = sg_phys(s);
 
                if (nonforced_iommu(dev, addr, s->length)) {
-                       addr = dma_map_area(dev, addr, s->length, dir);
+                       addr = dma_map_area(dev, addr, s->length, dir, 0);
                        if (addr == bad_dma_address) {
                                if (i > 0)
                                        gart_unmap_sg(dev, sg, i, dir);
@@ -362,7 +369,7 @@ static int __dma_map_cont(struct device *dev, struct scatterlist *start,
                          int nelems, struct scatterlist *sout,
                          unsigned long pages)
 {
-       unsigned long iommu_start = alloc_iommu(dev, pages);
+       unsigned long iommu_start = alloc_iommu(dev, pages, 0);
        unsigned long iommu_page = iommu_start;
        struct scatterlist *s;
        int i;
index bc1f2d3ea277817145cc7964f757c18ef3e21a51..a311ffcaad165c13032fc8972abc4bab44d251b4 100644 (file)
@@ -1,20 +1,13 @@
 #include <linux/platform_device.h>
-#include <linux/errno.h>
+#include <linux/err.h>
 #include <linux/init.h>
 
 static __init int add_pcspkr(void)
 {
        struct platform_device *pd;
-       int ret;
 
-       pd = platform_device_alloc("pcspkr", -1);
-       if (!pd)
-               return -ENOMEM;
+       pd = platform_device_register_simple("pcspkr", -1, NULL, 0);
 
-       ret = platform_device_add(pd);
-       if (ret)
-               platform_device_put(pd);
-
-       return ret;
+       return IS_ERR(pd) ? PTR_ERR(pd) : 0;
 }
 device_initcall(add_pcspkr);
index 876e91890777ae9758e5efcb7dc72075a26e341e..ec7a2ba9bce8062d870448ce5a5292b81b0d6dd8 100644 (file)
@@ -185,7 +185,8 @@ static void mwait_idle(void)
 static void poll_idle(void)
 {
        local_irq_enable();
-       cpu_relax();
+       while (!need_resched())
+               cpu_relax();
 }
 
 /*
index 31f40b24bf5d72f4d62c204307a1bd826c726c32..205188db96269c459d0d5cf739c6ce5495e082ea 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/tick.h>
 #include <linux/percpu.h>
 #include <linux/prctl.h>
+#include <linux/dmi.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -56,6 +57,8 @@
 #include <asm/cpu.h>
 #include <asm/kdebug.h>
 #include <asm/idle.h>
+#include <asm/syscalls.h>
+#include <asm/smp.h>
 
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
 
@@ -161,6 +164,7 @@ void __show_registers(struct pt_regs *regs, int all)
        unsigned long d0, d1, d2, d3, d6, d7;
        unsigned long sp;
        unsigned short ss, gs;
+       const char *board;
 
        if (user_mode_vm(regs)) {
                sp = regs->sp;
@@ -173,11 +177,15 @@ void __show_registers(struct pt_regs *regs, int all)
        }
 
        printk("\n");
-       printk("Pid: %d, comm: %s %s (%s %.*s)\n",
+
+       board = dmi_get_system_info(DMI_PRODUCT_NAME);
+       if (!board)
+               board = "";
+       printk("Pid: %d, comm: %s %s (%s %.*s) %s\n",
                        task_pid_nr(current), current->comm,
                        print_tainted(), init_utsname()->release,
                        (int)strcspn(init_utsname()->version, " "),
-                       init_utsname()->version);
+                       init_utsname()->version, board);
 
        printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n",
                        (u16)regs->cs, regs->ip, regs->flags,
@@ -277,6 +285,14 @@ void exit_thread(void)
                tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET;
                put_cpu();
        }
+#ifdef CONFIG_X86_DS
+       /* Free any DS contexts that have not been properly released. */
+       if (unlikely(current->thread.ds_ctx)) {
+               /* we clear debugctl to make sure DS is not used. */
+               update_debugctlmsr(0);
+               ds_free(current->thread.ds_ctx);
+       }
+#endif /* CONFIG_X86_DS */
 }
 
 void flush_thread(void)
@@ -438,6 +454,35 @@ int set_tsc_mode(unsigned int val)
        return 0;
 }
 
+#ifdef CONFIG_X86_DS
+static int update_debugctl(struct thread_struct *prev,
+                       struct thread_struct *next, unsigned long debugctl)
+{
+       unsigned long ds_prev = 0;
+       unsigned long ds_next = 0;
+
+       if (prev->ds_ctx)
+               ds_prev = (unsigned long)prev->ds_ctx->ds;
+       if (next->ds_ctx)
+               ds_next = (unsigned long)next->ds_ctx->ds;
+
+       if (ds_next != ds_prev) {
+               /* we clear debugctl to make sure DS
+                * is not in use when we change it */
+               debugctl = 0;
+               update_debugctlmsr(0);
+               wrmsr(MSR_IA32_DS_AREA, ds_next, 0);
+       }
+       return debugctl;
+}
+#else
+static int update_debugctl(struct thread_struct *prev,
+                       struct thread_struct *next, unsigned long debugctl)
+{
+       return debugctl;
+}
+#endif /* CONFIG_X86_DS */
+
 static noinline void
 __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
                 struct tss_struct *tss)
@@ -448,14 +493,7 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
        prev = &prev_p->thread;
        next = &next_p->thread;
 
-       debugctl = prev->debugctlmsr;
-       if (next->ds_area_msr != prev->ds_area_msr) {
-               /* we clear debugctl to make sure DS
-                * is not in use when we change it */
-               debugctl = 0;
-               update_debugctlmsr(0);
-               wrmsr(MSR_IA32_DS_AREA, next->ds_area_msr, 0);
-       }
+       debugctl = update_debugctl(prev, next, prev->debugctlmsr);
 
        if (next->debugctlmsr != debugctl)
                update_debugctlmsr(next->debugctlmsr);
@@ -479,13 +517,13 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
                        hard_enable_TSC();
        }
 
-#ifdef X86_BTS
+#ifdef CONFIG_X86_PTRACE_BTS
        if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS))
                ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS);
 
        if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS))
                ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES);
-#endif
+#endif /* CONFIG_X86_PTRACE_BTS */
 
 
        if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) {
index e12e0e4dd2566c2959623d4475053c5fcbcd65d3..2a8ccb9238b4719036aef70780b282e60f58acdd 100644 (file)
 #include <linux/kdebug.h>
 #include <linux/tick.h>
 #include <linux/prctl.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
 
-#include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
-#include <asm/io.h>
 #include <asm/processor.h>
 #include <asm/i387.h>
 #include <asm/mmu_context.h>
@@ -51,6 +51,7 @@
 #include <asm/proto.h>
 #include <asm/ia32.h>
 #include <asm/idle.h>
+#include <asm/syscalls.h>
 
 asmlinkage extern void ret_from_fork(void);
 
@@ -88,7 +89,7 @@ void exit_idle(void)
 #ifdef CONFIG_HOTPLUG_CPU
 DECLARE_PER_CPU(int, cpu_state);
 
-#include <asm/nmi.h>
+#include <linux/nmi.h>
 /* We halt the CPU with physical CPU hotplug */
 static inline void play_dead(void)
 {
@@ -153,7 +154,7 @@ void cpu_idle(void)
 }
 
 /* Prints also some state that isn't saved in the pt_regs */
-void __show_regs(struct pt_regs * regs)
+void __show_regs(struct pt_regs *regs)
 {
        unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L, fs, gs, shadowgs;
        unsigned long d0, d1, d2, d3, d6, d7;
@@ -162,59 +163,61 @@ void __show_regs(struct pt_regs * regs)
 
        printk("\n");
        print_modules();
-       printk("Pid: %d, comm: %.20s %s %s %.*s\n",
+       printk(KERN_INFO "Pid: %d, comm: %.20s %s %s %.*s\n",
                current->pid, current->comm, print_tainted(),
                init_utsname()->release,
                (int)strcspn(init_utsname()->version, " "),
                init_utsname()->version);
-       printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip);
+       printk(KERN_INFO "RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip);
        printk_address(regs->ip, 1);
-       printk("RSP: %04lx:%016lx  EFLAGS: %08lx\n", regs->ss, regs->sp,
-               regs->flags);
-       printk("RAX: %016lx RBX: %016lx RCX: %016lx\n",
+       printk(KERN_INFO "RSP: %04lx:%016lx  EFLAGS: %08lx\n", regs->ss,
+                       regs->sp, regs->flags);
+       printk(KERN_INFO "RAX: %016lx RBX: %016lx RCX: %016lx\n",
               regs->ax, regs->bx, regs->cx);
-       printk("RDX: %016lx RSI: %016lx RDI: %016lx\n",
+       printk(KERN_INFO "RDX: %016lx RSI: %016lx RDI: %016lx\n",
               regs->dx, regs->si, regs->di);
-       printk("RBP: %016lx R08: %016lx R09: %016lx\n",
+       printk(KERN_INFO "RBP: %016lx R08: %016lx R09: %016lx\n",
               regs->bp, regs->r8, regs->r9);
-       printk("R10: %016lx R11: %016lx R12: %016lx\n",
-              regs->r10, regs->r11, regs->r12); 
-       printk("R13: %016lx R14: %016lx R15: %016lx\n",
-              regs->r13, regs->r14, regs->r15); 
-
-       asm("movl %%ds,%0" : "=r" (ds)); 
-       asm("movl %%cs,%0" : "=r" (cs)); 
-       asm("movl %%es,%0" : "=r" (es)); 
+       printk(KERN_INFO "R10: %016lx R11: %016lx R12: %016lx\n",
+              regs->r10, regs->r11, regs->r12);
+       printk(KERN_INFO "R13: %016lx R14: %016lx R15: %016lx\n",
+              regs->r13, regs->r14, regs->r15);
+
+       asm("movl %%ds,%0" : "=r" (ds));
+       asm("movl %%cs,%0" : "=r" (cs));
+       asm("movl %%es,%0" : "=r" (es));
        asm("movl %%fs,%0" : "=r" (fsindex));
        asm("movl %%gs,%0" : "=r" (gsindex));
 
        rdmsrl(MSR_FS_BASE, fs);
-       rdmsrl(MSR_GS_BASE, gs); 
-       rdmsrl(MSR_KERNEL_GS_BASE, shadowgs); 
+       rdmsrl(MSR_GS_BASE, gs);
+       rdmsrl(MSR_KERNEL_GS_BASE, shadowgs);
 
        cr0 = read_cr0();
        cr2 = read_cr2();
        cr3 = read_cr3();
        cr4 = read_cr4();
 
-       printk("FS:  %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n", 
-              fs,fsindex,gs,gsindex,shadowgs); 
-       printk("CS:  %04x DS: %04x ES: %04x CR0: %016lx\n", cs, ds, es, cr0); 
-       printk("CR2: %016lx CR3: %016lx CR4: %016lx\n", cr2, cr3, cr4);
+       printk(KERN_INFO "FS:  %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n",
+              fs, fsindex, gs, gsindex, shadowgs);
+       printk(KERN_INFO "CS:  %04x DS: %04x ES: %04x CR0: %016lx\n", cs, ds,
+                       es, cr0);
+       printk(KERN_INFO "CR2: %016lx CR3: %016lx CR4: %016lx\n", cr2, cr3,
+                       cr4);
 
        get_debugreg(d0, 0);
        get_debugreg(d1, 1);
        get_debugreg(d2, 2);
-       printk("DR0: %016lx DR1: %016lx DR2: %016lx\n", d0, d1, d2);
+       printk(KERN_INFO "DR0: %016lx DR1: %016lx DR2: %016lx\n", d0, d1, d2);
        get_debugreg(d3, 3);
        get_debugreg(d6, 6);
        get_debugreg(d7, 7);
-       printk("DR3: %016lx DR6: %016lx DR7: %016lx\n", d3, d6, d7);
+       printk(KERN_INFO "DR3: %016lx DR6: %016lx DR7: %016lx\n", d3, d6, d7);
 }
 
 void show_regs(struct pt_regs *regs)
 {
-       printk("CPU %d:", smp_processor_id());
+       printk(KERN_INFO "CPU %d:", smp_processor_id());
        __show_regs(regs);
        show_trace(NULL, regs, (void *)(regs + 1), regs->bp);
 }
@@ -240,6 +243,14 @@ void exit_thread(void)
                t->io_bitmap_max = 0;
                put_cpu();
        }
+#ifdef CONFIG_X86_DS
+       /* Free any DS contexts that have not been properly released. */
+       if (unlikely(t->ds_ctx)) {
+               /* we clear debugctl to make sure DS is not used. */
+               update_debugctlmsr(0);
+               ds_free(t->ds_ctx);
+       }
+#endif /* CONFIG_X86_DS */
 }
 
 void flush_thread(void)
@@ -315,10 +326,10 @@ void prepare_to_copy(struct task_struct *tsk)
 
 int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
                unsigned long unused,
-       struct task_struct * p, struct pt_regs * regs)
+       struct task_struct *p, struct pt_regs *regs)
 {
        int err;
-       struct pt_regs * childregs;
+       struct pt_regs *childregs;
        struct task_struct *me = current;
 
        childregs = ((struct pt_regs *)
@@ -363,10 +374,10 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
                if (test_thread_flag(TIF_IA32))
                        err = do_set_thread_area(p, -1,
                                (struct user_desc __user *)childregs->si, 0);
-               else                    
-#endif  
-                       err = do_arch_prctl(p, ARCH_SET_FS, childregs->r8); 
-               if (err) 
+               else
+#endif
+                       err = do_arch_prctl(p, ARCH_SET_FS, childregs->r8);
+               if (err)
                        goto out;
        }
        err = 0;
@@ -473,13 +484,27 @@ static inline void __switch_to_xtra(struct task_struct *prev_p,
        next = &next_p->thread;
 
        debugctl = prev->debugctlmsr;
-       if (next->ds_area_msr != prev->ds_area_msr) {
-               /* we clear debugctl to make sure DS
-                * is not in use when we change it */
-               debugctl = 0;
-               update_debugctlmsr(0);
-               wrmsrl(MSR_IA32_DS_AREA, next->ds_area_msr);
+
+#ifdef CONFIG_X86_DS
+       {
+               unsigned long ds_prev = 0, ds_next = 0;
+
+               if (prev->ds_ctx)
+                       ds_prev = (unsigned long)prev->ds_ctx->ds;
+               if (next->ds_ctx)
+                       ds_next = (unsigned long)next->ds_ctx->ds;
+
+               if (ds_next != ds_prev) {
+                       /*
+                        * We clear debugctl to make sure DS
+                        * is not in use when we change it:
+                        */
+                       debugctl = 0;
+                       update_debugctlmsr(0);
+                       wrmsrl(MSR_IA32_DS_AREA, ds_next);
+               }
        }
+#endif /* CONFIG_X86_DS */
 
        if (next->debugctlmsr != debugctl)
                update_debugctlmsr(next->debugctlmsr);
@@ -517,13 +542,13 @@ static inline void __switch_to_xtra(struct task_struct *prev_p,
                memset(tss->io_bitmap, 0xff, prev->io_bitmap_max);
        }
 
-#ifdef X86_BTS
+#ifdef CONFIG_X86_PTRACE_BTS
        if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS))
                ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS);
 
        if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS))
                ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES);
-#endif
+#endif /* CONFIG_X86_PTRACE_BTS */
 }
 
 /*
@@ -545,7 +570,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
        unsigned fsindex, gsindex;
 
        /* we're going to use this soon, after a few expensive things */
-       if (next_p->fpu_counter>5)
+       if (next_p->fpu_counter > 5)
                prefetch(next->xstate);
 
        /*
@@ -553,13 +578,13 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
         */
        load_sp0(tss, next);
 
-       /* 
+       /*
         * Switch DS and ES.
         * This won't pick up thread selector changes, but I guess that is ok.
         */
        savesegment(es, prev->es);
        if (unlikely(next->es | prev->es))
-               loadsegment(es, next->es); 
+               loadsegment(es, next->es);
 
        savesegment(ds, prev->ds);
        if (unlikely(next->ds | prev->ds))
@@ -585,7 +610,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
         */
        arch_leave_lazy_cpu_mode();
 
-       /* 
+       /*
         * Switch FS and GS.
         *
         * Segment register != 0 always requires a reload.  Also
@@ -594,13 +619,13 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
         */
        if (unlikely(fsindex | next->fsindex | prev->fs)) {
                loadsegment(fs, next->fsindex);
-               /* 
+               /*
                 * Check if the user used a selector != 0; if yes
                 *  clear 64bit base, since overloaded base is always
                 *  mapped to the Null selector
                 */
                if (fsindex)
-                       prev->fs = 0;                           
+                       prev->fs = 0;
        }
        /* when next process has a 64bit base use it */
        if (next->fs)
@@ -610,7 +635,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
        if (unlikely(gsindex | next->gsindex | prev->gs)) {
                load_gs_index(next->gsindex);
                if (gsindex)
-                       prev->gs = 0;                           
+                       prev->gs = 0;
        }
        if (next->gs)
                wrmsrl(MSR_KERNEL_GS_BASE, next->gs);
@@ -619,12 +644,12 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
        /* Must be after DS reload */
        unlazy_fpu(prev_p);
 
-       /* 
+       /*
         * Switch the PDA and FPU contexts.
         */
        prev->usersp = read_pda(oldrsp);
        write_pda(oldrsp, next->usersp);
-       write_pda(pcurrent, next_p); 
+       write_pda(pcurrent, next_p);
 
        write_pda(kernelstack,
                  (unsigned long)task_stack_page(next_p) +
@@ -665,7 +690,7 @@ long sys_execve(char __user *name, char __user * __user *argv,
                char __user * __user *envp, struct pt_regs *regs)
 {
        long error;
-       char * filename;
+       char *filename;
 
        filename = getname(name);
        error = PTR_ERR(filename);
@@ -723,55 +748,55 @@ asmlinkage long sys_vfork(struct pt_regs *regs)
 unsigned long get_wchan(struct task_struct *p)
 {
        unsigned long stack;
-       u64 fp,ip;
+       u64 fp, ip;
        int count = 0;
 
-       if (!p || p == current || p->state==TASK_RUNNING)
-               return 0; 
+       if (!p || p == current || p->state == TASK_RUNNING)
+               return 0;
        stack = (unsigned long)task_stack_page(p);
        if (p->thread.sp < stack || p->thread.sp > stack+THREAD_SIZE)
                return 0;
        fp = *(u64 *)(p->thread.sp);
-       do { 
+       do {
                if (fp < (unsigned long)stack ||
                    fp > (unsigned long)stack+THREAD_SIZE)
-                       return 0; 
+                       return 0;
                ip = *(u64 *)(fp+8);
                if (!in_sched_functions(ip))
                        return ip;
-               fp = *(u64 *)fp; 
-       } while (count++ < 16); 
+               fp = *(u64 *)fp;
+       } while (count++ < 16);
        return 0;
 }
 
 long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
-{ 
-       int ret = 0; 
+{
+       int ret = 0;
        int doit = task == current;
        int cpu;
 
-       switch (code) { 
+       switch (code) {
        case ARCH_SET_GS:
                if (addr >= TASK_SIZE_OF(task))
-                       return -EPERM; 
+                       return -EPERM;
                cpu = get_cpu();
-               /* handle small bases via the GDT because that's faster to 
+               /* handle small bases via the GDT because that's faster to
                   switch. */
-               if (addr <= 0xffffffff) {  
-                       set_32bit_tls(task, GS_TLS, addr); 
-                       if (doit) { 
+               if (addr <= 0xffffffff) {
+                       set_32bit_tls(task, GS_TLS, addr);
+                       if (doit) {
                                load_TLS(&task->thread, cpu);
-                               load_gs_index(GS_TLS_SEL); 
+                               load_gs_index(GS_TLS_SEL);
                        }
-                       task->thread.gsindex = GS_TLS_SEL; 
+                       task->thread.gsindex = GS_TLS_SEL;
                        task->thread.gs = 0;
-               } else { 
+               } else {
                        task->thread.gsindex = 0;
                        task->thread.gs = addr;
                        if (doit) {
                                load_gs_index(0);
                                ret = checking_wrmsrl(MSR_KERNEL_GS_BASE, addr);
-                       } 
+                       }
                }
                put_cpu();
                break;
@@ -825,8 +850,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
                                rdmsrl(MSR_KERNEL_GS_BASE, base);
                        else
                                base = task->thread.gs;
-               }
-               else
+               } else
                        base = task->thread.gs;
                ret = put_user(base, (unsigned long __user *)addr);
                break;
index e37dccce85db5e15922602b833a3821b78ca4ffd..e375b658efc316e4e14785b7f2a3ad61e763cd82 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/errno.h>
 #include <linux/ptrace.h>
 #include <linux/regset.h>
+#include <linux/tracehook.h>
 #include <linux/user.h>
 #include <linux/elf.h>
 #include <linux/security.h>
@@ -69,7 +70,7 @@ static inline bool invalid_selector(u16 value)
 
 #define FLAG_MASK              FLAG_MASK_32
 
-static long *pt_regs_access(struct pt_regs *regs, unsigned long regno)
+static unsigned long *pt_regs_access(struct pt_regs *regs, unsigned long regno)
 {
        BUILD_BUG_ON(offsetof(struct pt_regs, bx) != 0);
        regno >>= 2;
@@ -554,45 +555,115 @@ static int ptrace_set_debugreg(struct task_struct *child,
        return 0;
 }
 
-#ifdef X86_BTS
+#ifdef CONFIG_X86_PTRACE_BTS
+/*
+ * The configuration for a particular BTS hardware implementation.
+ */
+struct bts_configuration {
+       /* the size of a BTS record in bytes; at most BTS_MAX_RECORD_SIZE */
+       unsigned char  sizeof_bts;
+       /* the size of a field in the BTS record in bytes */
+       unsigned char  sizeof_field;
+       /* a bitmask to enable/disable BTS in DEBUGCTL MSR */
+       unsigned long debugctl_mask;
+};
+static struct bts_configuration bts_cfg;
+
+#define BTS_MAX_RECORD_SIZE (8 * 3)
+
+
+/*
+ * Branch Trace Store (BTS) uses the following format. Different
+ * architectures vary in the size of those fields.
+ * - source linear address
+ * - destination linear address
+ * - flags
+ *
+ * Later architectures use 64bit pointers throughout, whereas earlier
+ * architectures use 32bit pointers in 32bit mode.
+ *
+ * We compute the base address for the first 8 fields based on:
+ * - the field size stored in the DS configuration
+ * - the relative field position
+ *
+ * In order to store additional information in the BTS buffer, we use
+ * a special source address to indicate that the record requires
+ * special interpretation.
+ *
+ * Netburst indicated via a bit in the flags field whether the branch
+ * was predicted; this is ignored.
+ */
+
+enum bts_field {
+       bts_from = 0,
+       bts_to,
+       bts_flags,
+
+       bts_escape = (unsigned long)-1,
+       bts_qual = bts_to,
+       bts_jiffies = bts_flags
+};
+
+static inline unsigned long bts_get(const char *base, enum bts_field field)
+{
+       base += (bts_cfg.sizeof_field * field);
+       return *(unsigned long *)base;
+}
 
-static int ptrace_bts_get_size(struct task_struct *child)
+static inline void bts_set(char *base, enum bts_field field, unsigned long val)
 {
-       if (!child->thread.ds_area_msr)
-               return -ENXIO;
+       base += (bts_cfg.sizeof_field * field);;
+       (*(unsigned long *)base) = val;
+}
 
-       return ds_get_bts_index((void *)child->thread.ds_area_msr);
+/*
+ * Translate a BTS record from the raw format into the bts_struct format
+ *
+ * out (out): bts_struct interpretation
+ * raw: raw BTS record
+ */
+static void ptrace_bts_translate_record(struct bts_struct *out, const void *raw)
+{
+       memset(out, 0, sizeof(*out));
+       if (bts_get(raw, bts_from) == bts_escape) {
+               out->qualifier       = bts_get(raw, bts_qual);
+               out->variant.jiffies = bts_get(raw, bts_jiffies);
+       } else {
+               out->qualifier = BTS_BRANCH;
+               out->variant.lbr.from_ip = bts_get(raw, bts_from);
+               out->variant.lbr.to_ip   = bts_get(raw, bts_to);
+       }
 }
 
-static int ptrace_bts_read_record(struct task_struct *child,
-                                 long index,
+static int ptrace_bts_read_record(struct task_struct *child, size_t index,
                                  struct bts_struct __user *out)
 {
        struct bts_struct ret;
-       int retval;
-       int bts_end;
-       int bts_index;
-
-       if (!child->thread.ds_area_msr)
-               return -ENXIO;
+       const void *bts_record;
+       size_t bts_index, bts_end;
+       int error;
 
-       if (index < 0)
-               return -EINVAL;
+       error = ds_get_bts_end(child, &bts_end);
+       if (error < 0)
+               return error;
 
-       bts_end = ds_get_bts_end((void *)child->thread.ds_area_msr);
        if (bts_end <= index)
                return -EINVAL;
 
+       error = ds_get_bts_index(child, &bts_index);
+       if (error < 0)
+               return error;
+
        /* translate the ptrace bts index into the ds bts index */
-       bts_index = ds_get_bts_index((void *)child->thread.ds_area_msr);
-       bts_index -= (index + 1);
-       if (bts_index < 0)
-               bts_index += bts_end;
+       bts_index += bts_end - (index + 1);
+       if (bts_end <= bts_index)
+               bts_index -= bts_end;
 
-       retval = ds_read_bts((void *)child->thread.ds_area_msr,
-                            bts_index, &ret);
-       if (retval < 0)
-               return retval;
+       error = ds_access_bts(child, bts_index, &bts_record);
+       if (error < 0)
+               return error;
+
+       ptrace_bts_translate_record(&ret, bts_record);
 
        if (copy_to_user(out, &ret, sizeof(ret)))
                return -EFAULT;
@@ -600,101 +671,106 @@ static int ptrace_bts_read_record(struct task_struct *child,
        return sizeof(ret);
 }
 
-static int ptrace_bts_clear(struct task_struct *child)
-{
-       if (!child->thread.ds_area_msr)
-               return -ENXIO;
-
-       return ds_clear((void *)child->thread.ds_area_msr);
-}
-
 static int ptrace_bts_drain(struct task_struct *child,
                            long size,
                            struct bts_struct __user *out)
 {
-       int end, i;
-       void *ds = (void *)child->thread.ds_area_msr;
-
-       if (!ds)
-               return -ENXIO;
+       struct bts_struct ret;
+       const unsigned char *raw;
+       size_t end, i;
+       int error;
 
-       end = ds_get_bts_index(ds);
-       if (end <= 0)
-               return end;
+       error = ds_get_bts_index(child, &end);
+       if (error < 0)
+               return error;
 
        if (size < (end * sizeof(struct bts_struct)))
                return -EIO;
 
-       for (i = 0; i < end; i++, out++) {
-               struct bts_struct ret;
-               int retval;
+       error = ds_access_bts(child, 0, (const void **)&raw);
+       if (error < 0)
+               return error;
 
-               retval = ds_read_bts(ds, i, &ret);
-               if (retval < 0)
-                       return retval;
+       for (i = 0; i < end; i++, out++, raw += bts_cfg.sizeof_bts) {
+               ptrace_bts_translate_record(&ret, raw);
 
                if (copy_to_user(out, &ret, sizeof(ret)))
                        return -EFAULT;
        }
 
-       ds_clear(ds);
+       error = ds_clear_bts(child);
+       if (error < 0)
+               return error;
 
        return end;
 }
 
+static void ptrace_bts_ovfl(struct task_struct *child)
+{
+       send_sig(child->thread.bts_ovfl_signal, child, 0);
+}
+
 static int ptrace_bts_config(struct task_struct *child,
                             long cfg_size,
                             const struct ptrace_bts_config __user *ucfg)
 {
        struct ptrace_bts_config cfg;
-       int bts_size, ret = 0;
-       void *ds;
+       int error = 0;
+
+       error = -EOPNOTSUPP;
+       if (!bts_cfg.sizeof_bts)
+               goto errout;
 
+       error = -EIO;
        if (cfg_size < sizeof(cfg))
-               return -EIO;
+               goto errout;
 
+       error = -EFAULT;
        if (copy_from_user(&cfg, ucfg, sizeof(cfg)))
-               return -EFAULT;
+               goto errout;
 
-       if ((int)cfg.size < 0)
-               return -EINVAL;
+       error = -EINVAL;
+       if ((cfg.flags & PTRACE_BTS_O_SIGNAL) &&
+           !(cfg.flags & PTRACE_BTS_O_ALLOC))
+               goto errout;
 
-       bts_size = 0;
-       ds = (void *)child->thread.ds_area_msr;
-       if (ds) {
-               bts_size = ds_get_bts_size(ds);
-               if (bts_size < 0)
-                       return bts_size;
-       }
-       cfg.size = PAGE_ALIGN(cfg.size);
+       if (cfg.flags & PTRACE_BTS_O_ALLOC) {
+               ds_ovfl_callback_t ovfl = NULL;
+               unsigned int sig = 0;
+
+               /* we ignore the error in case we were not tracing child */
+               (void)ds_release_bts(child);
 
-       if (bts_size != cfg.size) {
-               ret = ptrace_bts_realloc(child, cfg.size,
-                                        cfg.flags & PTRACE_BTS_O_CUT_SIZE);
-               if (ret < 0)
+               if (cfg.flags & PTRACE_BTS_O_SIGNAL) {
+                       if (!cfg.signal)
+                               goto errout;
+
+                       sig  = cfg.signal;
+                       ovfl = ptrace_bts_ovfl;
+               }
+
+               error = ds_request_bts(child, /* base = */ NULL, cfg.size, ovfl);
+               if (error < 0)
                        goto errout;
 
-               ds = (void *)child->thread.ds_area_msr;
+               child->thread.bts_ovfl_signal = sig;
        }
 
-       if (cfg.flags & PTRACE_BTS_O_SIGNAL)
-               ret = ds_set_overflow(ds, DS_O_SIGNAL);
-       else
-               ret = ds_set_overflow(ds, DS_O_WRAP);
-       if (ret < 0)
+       error = -EINVAL;
+       if (!child->thread.ds_ctx && cfg.flags)
                goto errout;
 
        if (cfg.flags & PTRACE_BTS_O_TRACE)
-               child->thread.debugctlmsr |= ds_debugctl_mask();
+               child->thread.debugctlmsr |= bts_cfg.debugctl_mask;
        else
-               child->thread.debugctlmsr &= ~ds_debugctl_mask();
+               child->thread.debugctlmsr &= ~bts_cfg.debugctl_mask;
 
        if (cfg.flags & PTRACE_BTS_O_SCHED)
                set_tsk_thread_flag(child, TIF_BTS_TRACE_TS);
        else
                clear_tsk_thread_flag(child, TIF_BTS_TRACE_TS);
 
-       ret = sizeof(cfg);
+       error = sizeof(cfg);
 
 out:
        if (child->thread.debugctlmsr)
@@ -702,10 +778,10 @@ out:
        else
                clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR);
 
-       return ret;
+       return error;
 
 errout:
-       child->thread.debugctlmsr &= ~ds_debugctl_mask();
+       child->thread.debugctlmsr &= ~bts_cfg.debugctl_mask;
        clear_tsk_thread_flag(child, TIF_BTS_TRACE_TS);
        goto out;
 }
@@ -714,29 +790,40 @@ static int ptrace_bts_status(struct task_struct *child,
                             long cfg_size,
                             struct ptrace_bts_config __user *ucfg)
 {
-       void *ds = (void *)child->thread.ds_area_msr;
        struct ptrace_bts_config cfg;
+       size_t end;
+       const void *base, *max;
+       int error;
 
        if (cfg_size < sizeof(cfg))
                return -EIO;
 
-       memset(&cfg, 0, sizeof(cfg));
+       error = ds_get_bts_end(child, &end);
+       if (error < 0)
+               return error;
 
-       if (ds) {
-               cfg.size = ds_get_bts_size(ds);
+       error = ds_access_bts(child, /* index = */ 0, &base);
+       if (error < 0)
+               return error;
 
-               if (ds_get_overflow(ds) == DS_O_SIGNAL)
-                       cfg.flags |= PTRACE_BTS_O_SIGNAL;
+       error = ds_access_bts(child, /* index = */ end, &max);
+       if (error < 0)
+               return error;
 
-               if (test_tsk_thread_flag(child, TIF_DEBUGCTLMSR) &&
-                   child->thread.debugctlmsr & ds_debugctl_mask())
-                       cfg.flags |= PTRACE_BTS_O_TRACE;
+       memset(&cfg, 0, sizeof(cfg));
+       cfg.size = (max - base);
+       cfg.signal = child->thread.bts_ovfl_signal;
+       cfg.bts_size = sizeof(struct bts_struct);
 
-               if (test_tsk_thread_flag(child, TIF_BTS_TRACE_TS))
-                       cfg.flags |= PTRACE_BTS_O_SCHED;
-       }
+       if (cfg.signal)
+               cfg.flags |= PTRACE_BTS_O_SIGNAL;
 
-       cfg.bts_size = sizeof(struct bts_struct);
+       if (test_tsk_thread_flag(child, TIF_DEBUGCTLMSR) &&
+           child->thread.debugctlmsr & bts_cfg.debugctl_mask)
+               cfg.flags |= PTRACE_BTS_O_TRACE;
+
+       if (test_tsk_thread_flag(child, TIF_BTS_TRACE_TS))
+               cfg.flags |= PTRACE_BTS_O_SCHED;
 
        if (copy_to_user(ucfg, &cfg, sizeof(cfg)))
                return -EFAULT;
@@ -744,89 +831,38 @@ static int ptrace_bts_status(struct task_struct *child,
        return sizeof(cfg);
 }
 
-
 static int ptrace_bts_write_record(struct task_struct *child,
                                   const struct bts_struct *in)
 {
-       int retval;
+       unsigned char bts_record[BTS_MAX_RECORD_SIZE];
 
-       if (!child->thread.ds_area_msr)
-               return -ENXIO;
+       BUG_ON(BTS_MAX_RECORD_SIZE < bts_cfg.sizeof_bts);
 
-       retval = ds_write_bts((void *)child->thread.ds_area_msr, in);
-       if (retval)
-               return retval;
+       memset(bts_record, 0, bts_cfg.sizeof_bts);
+       switch (in->qualifier) {
+       case BTS_INVALID:
+               break;
 
-       return sizeof(*in);
-}
+       case BTS_BRANCH:
+               bts_set(bts_record, bts_from, in->variant.lbr.from_ip);
+               bts_set(bts_record, bts_to,   in->variant.lbr.to_ip);
+               break;
 
-static int ptrace_bts_realloc(struct task_struct *child,
-                             int size, int reduce_size)
-{
-       unsigned long rlim, vm;
-       int ret, old_size;
+       case BTS_TASK_ARRIVES:
+       case BTS_TASK_DEPARTS:
+               bts_set(bts_record, bts_from,    bts_escape);
+               bts_set(bts_record, bts_qual,    in->qualifier);
+               bts_set(bts_record, bts_jiffies, in->variant.jiffies);
+               break;
 
-       if (size < 0)
+       default:
                return -EINVAL;
-
-       old_size = ds_get_bts_size((void *)child->thread.ds_area_msr);
-       if (old_size < 0)
-               return old_size;
-
-       ret = ds_free((void **)&child->thread.ds_area_msr);
-       if (ret < 0)
-               goto out;
-
-       size >>= PAGE_SHIFT;
-       old_size >>= PAGE_SHIFT;
-
-       current->mm->total_vm  -= old_size;
-       current->mm->locked_vm -= old_size;
-
-       if (size == 0)
-               goto out;
-
-       rlim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
-       vm = current->mm->total_vm  + size;
-       if (rlim < vm) {
-               ret = -ENOMEM;
-
-               if (!reduce_size)
-                       goto out;
-
-               size = rlim - current->mm->total_vm;
-               if (size <= 0)
-                       goto out;
-       }
-
-       rlim = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
-       vm = current->mm->locked_vm  + size;
-       if (rlim < vm) {
-               ret = -ENOMEM;
-
-               if (!reduce_size)
-                       goto out;
-
-               size = rlim - current->mm->locked_vm;
-               if (size <= 0)
-                       goto out;
        }
 
-       ret = ds_allocate((void **)&child->thread.ds_area_msr,
-                         size << PAGE_SHIFT);
-       if (ret < 0)
-               goto out;
-
-       current->mm->total_vm  += size;
-       current->mm->locked_vm += size;
-
-out:
-       if (child->thread.ds_area_msr)
-               set_tsk_thread_flag(child, TIF_DS_AREA_MSR);
-       else
-               clear_tsk_thread_flag(child, TIF_DS_AREA_MSR);
-
-       return ret;
+       /* The writing task will be the switched-to task on a context
+        * switch. It needs to write into the switched-from task's BTS
+        * buffer. */
+       return ds_unchecked_write_bts(child, bts_record, bts_cfg.sizeof_bts);
 }
 
 void ptrace_bts_take_timestamp(struct task_struct *tsk,
@@ -839,7 +875,66 @@ void ptrace_bts_take_timestamp(struct task_struct *tsk,
 
        ptrace_bts_write_record(tsk, &rec);
 }
-#endif /* X86_BTS */
+
+static const struct bts_configuration bts_cfg_netburst = {
+       .sizeof_bts    = sizeof(long) * 3,
+       .sizeof_field  = sizeof(long),
+       .debugctl_mask = (1<<2)|(1<<3)|(1<<5)
+};
+
+static const struct bts_configuration bts_cfg_pentium_m = {
+       .sizeof_bts    = sizeof(long) * 3,
+       .sizeof_field  = sizeof(long),
+       .debugctl_mask = (1<<6)|(1<<7)
+};
+
+static const struct bts_configuration bts_cfg_core2 = {
+       .sizeof_bts    = 8 * 3,
+       .sizeof_field  = 8,
+       .debugctl_mask = (1<<6)|(1<<7)|(1<<9)
+};
+
+static inline void bts_configure(const struct bts_configuration *cfg)
+{
+       bts_cfg = *cfg;
+}
+
+void __cpuinit ptrace_bts_init_intel(struct cpuinfo_x86 *c)
+{
+       switch (c->x86) {
+       case 0x6:
+               switch (c->x86_model) {
+               case 0xD:
+               case 0xE: /* Pentium M */
+                       bts_configure(&bts_cfg_pentium_m);
+                       break;
+               case 0xF: /* Core2 */
+        case 0x1C: /* Atom */
+                       bts_configure(&bts_cfg_core2);
+                       break;
+               default:
+                       /* sorry, don't know about them */
+                       break;
+               }
+               break;
+       case 0xF:
+               switch (c->x86_model) {
+               case 0x0:
+               case 0x1:
+               case 0x2: /* Netburst */
+                       bts_configure(&bts_cfg_netburst);
+                       break;
+               default:
+                       /* sorry, don't know about them */
+                       break;
+               }
+               break;
+       default:
+               /* sorry, don't know about them */
+               break;
+       }
+}
+#endif /* CONFIG_X86_PTRACE_BTS */
 
 /*
  * Called by kernel/ptrace.c when detaching..
@@ -852,15 +947,15 @@ void ptrace_disable(struct task_struct *child)
 #ifdef TIF_SYSCALL_EMU
        clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
 #endif
-       if (child->thread.ds_area_msr) {
-#ifdef X86_BTS
-               ptrace_bts_realloc(child, 0, 0);
-#endif
-               child->thread.debugctlmsr &= ~ds_debugctl_mask();
-               if (!child->thread.debugctlmsr)
-                       clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR);
-               clear_tsk_thread_flag(child, TIF_BTS_TRACE_TS);
-       }
+#ifdef CONFIG_X86_PTRACE_BTS
+       (void)ds_release_bts(child);
+
+       child->thread.debugctlmsr &= ~bts_cfg.debugctl_mask;
+       if (!child->thread.debugctlmsr)
+               clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR);
+
+       clear_tsk_thread_flag(child, TIF_BTS_TRACE_TS);
+#endif /* CONFIG_X86_PTRACE_BTS */
 }
 
 #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
@@ -980,7 +1075,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
        /*
         * These bits need more cooking - not enabled yet:
         */
-#ifdef X86_BTS
+#ifdef CONFIG_X86_PTRACE_BTS
        case PTRACE_BTS_CONFIG:
                ret = ptrace_bts_config
                        (child, data, (struct ptrace_bts_config __user *)addr);
@@ -992,7 +1087,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                break;
 
        case PTRACE_BTS_SIZE:
-               ret = ptrace_bts_get_size(child);
+               ret = ds_get_bts_index(child, /* pos = */ NULL);
                break;
 
        case PTRACE_BTS_GET:
@@ -1001,14 +1096,14 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                break;
 
        case PTRACE_BTS_CLEAR:
-               ret = ptrace_bts_clear(child);
+               ret = ds_clear_bts(child);
                break;
 
        case PTRACE_BTS_DRAIN:
                ret = ptrace_bts_drain
                        (child, data, (struct bts_struct __user *) addr);
                break;
-#endif
+#endif /* CONFIG_X86_PTRACE_BTS */
 
        default:
                ret = ptrace_request(child, request, addr, data);
@@ -1375,30 +1470,6 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
        force_sig_info(SIGTRAP, &info, tsk);
 }
 
-static void syscall_trace(struct pt_regs *regs)
-{
-       if (!(current->ptrace & PT_PTRACED))
-               return;
-
-#if 0
-       printk("trace %s ip %lx sp %lx ax %d origrax %d caller %lx tiflags %x ptrace %x\n",
-              current->comm,
-              regs->ip, regs->sp, regs->ax, regs->orig_ax, __builtin_return_address(0),
-              current_thread_info()->flags, current->ptrace);
-#endif
-
-       ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
-                               ? 0x80 : 0));
-       /*
-        * this isn't the same as continuing with a signal, but it will do
-        * for normal use.  strace only continues with a signal if the
-        * stopping signal is not SIGTRAP.  -brl
-        */
-       if (current->exit_code) {
-               send_sig(current->exit_code, current, 1);
-               current->exit_code = 0;
-       }
-}
 
 #ifdef CONFIG_X86_32
 # define IS_IA32       1
@@ -1432,8 +1503,9 @@ asmregparm long syscall_trace_enter(struct pt_regs *regs)
        if (unlikely(test_thread_flag(TIF_SYSCALL_EMU)))
                ret = -1L;
 
-       if (ret || test_thread_flag(TIF_SYSCALL_TRACE))
-               syscall_trace(regs);
+       if ((ret || test_thread_flag(TIF_SYSCALL_TRACE)) &&
+           tracehook_report_syscall_entry(regs))
+               ret = -1L;
 
        if (unlikely(current->audit_context)) {
                if (IS_IA32)
@@ -1459,7 +1531,7 @@ asmregparm void syscall_trace_leave(struct pt_regs *regs)
                audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax);
 
        if (test_thread_flag(TIF_SYSCALL_TRACE))
-               syscall_trace(regs);
+               tracehook_report_syscall_exit(regs, 0);
 
        /*
         * If TIF_SYSCALL_EMU is set, we only get here because of
@@ -1475,6 +1547,6 @@ asmregparm void syscall_trace_leave(struct pt_regs *regs)
         * system call instruction.
         */
        if (test_thread_flag(TIF_SINGLESTEP) &&
-           (current->ptrace & PT_PTRACED))
+           tracehook_consider_fatal_signal(current, SIGTRAP, SIG_DFL))
                send_sigtrap(current, regs, 0);
 }
index 724adfc63cb9a7b60d6ee5c82efd919fe237f69c..f4c93f1cfc194767285bec90047c5db7ed13b758 100644 (file)
@@ -29,7 +29,11 @@ EXPORT_SYMBOL(pm_power_off);
 
 static const struct desc_ptr no_idt = {};
 static int reboot_mode;
-enum reboot_type reboot_type = BOOT_KBD;
+/*
+ * Keyboard reset and triple fault may result in INIT, not RESET, which
+ * doesn't work when we're in vmx root mode.  Try ACPI first.
+ */
+enum reboot_type reboot_type = BOOT_ACPI;
 int reboot_force;
 
 #if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
index 9838f2539dfc4cb93697a98a98752012b885a2d7..141efab52400fe7919d1ad573ba1b54e407c9ac6 100644 (file)
@@ -223,6 +223,9 @@ unsigned long saved_video_mode;
 #define RAMDISK_LOAD_FLAG              0x4000
 
 static char __initdata command_line[COMMAND_LINE_SIZE];
+#ifdef CONFIG_CMDLINE_BOOL
+static char __initdata builtin_cmdline[COMMAND_LINE_SIZE] = CONFIG_CMDLINE;
+#endif
 
 #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
 struct edd edd;
@@ -665,6 +668,19 @@ void __init setup_arch(char **cmdline_p)
        bss_resource.start = virt_to_phys(&__bss_start);
        bss_resource.end = virt_to_phys(&__bss_stop)-1;
 
+#ifdef CONFIG_CMDLINE_BOOL
+#ifdef CONFIG_CMDLINE_OVERRIDE
+       strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
+#else
+       if (builtin_cmdline[0]) {
+               /* append boot loader cmdline to builtin */
+               strlcat(builtin_cmdline, " ", COMMAND_LINE_SIZE);
+               strlcat(builtin_cmdline, boot_command_line, COMMAND_LINE_SIZE);
+               strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
+       }
+#endif
+#endif
+
        strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
        *cmdline_p = command_line;
 
index 76e305e064f96f9f7ece081665de18e7fb189e9a..0e67f72d931683413160a007d554c44a438c2c28 100644 (file)
@@ -162,9 +162,16 @@ void __init setup_per_cpu_areas(void)
                        printk(KERN_INFO
                               "cpu %d has no node %d or node-local memory\n",
                                cpu, node);
+                       if (ptr)
+                               printk(KERN_DEBUG "per cpu data for cpu%d at %016lx\n",
+                                        cpu, __pa(ptr));
                }
-               else
+               else {
                        ptr = alloc_bootmem_pages_node(NODE_DATA(node), size);
+                       if (ptr)
+                               printk(KERN_DEBUG "per cpu data for cpu%d on node%d at %016lx\n",
+                                        cpu, node, __pa(ptr));
+               }
 #endif
                per_cpu_offset(cpu) = ptr - __per_cpu_start;
                memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
index 72bbb519d2dc1ed74e6f01d39842995871ed9e80..8b4956e800acd4394c06e303989982c85ad04e53 100644 (file)
@@ -24,4 +24,9 @@ struct rt_sigframe {
        struct ucontext uc;
        struct siginfo info;
 };
+
+int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+               sigset_t *set, struct pt_regs *regs);
+int ia32_setup_frame(int sig, struct k_sigaction *ka,
+               sigset_t *set, struct pt_regs *regs);
 #endif
index 6fb5bcdd893366c66ccae845f2b1a20c076fa2f3..2a2435d3037d9ac9dd8fab949c3c57c775e426e4 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/wait.h>
+#include <linux/tracehook.h>
 #include <linux/elf.h>
 #include <linux/smp.h>
 #include <linux/mm.h>
@@ -26,6 +27,7 @@
 #include <asm/uaccess.h>
 #include <asm/i387.h>
 #include <asm/vdso.h>
+#include <asm/syscalls.h>
 
 #include "sigframe.h"
 
@@ -558,8 +560,6 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
         * handler too.
         */
        regs->flags &= ~X86_EFLAGS_TF;
-       if (test_thread_flag(TIF_SINGLESTEP))
-               ptrace_notify(SIGTRAP);
 
        spin_lock_irq(&current->sighand->siglock);
        sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
@@ -568,6 +568,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
        recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
 
+       tracehook_signal_handler(sig, info, ka, regs,
+                                test_thread_flag(TIF_SINGLESTEP));
+
        return 0;
 }
 
@@ -661,5 +664,10 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
        if (thread_info_flags & _TIF_SIGPENDING)
                do_signal(regs);
 
+       if (thread_info_flags & _TIF_NOTIFY_RESUME) {
+               clear_thread_flag(TIF_NOTIFY_RESUME);
+               tracehook_notify_resume(regs);
+       }
+
        clear_thread_flag(TIF_IRET);
 }
index ca316b5b742ced782dc3ab4b4c8631b5a9d43a6c..694aa888bb1993d7d7a38f8fe09b15a607867c7c 100644 (file)
 #include <linux/errno.h>
 #include <linux/wait.h>
 #include <linux/ptrace.h>
+#include <linux/tracehook.h>
 #include <linux/unistd.h>
 #include <linux/stddef.h>
 #include <linux/personality.h>
 #include <linux/compiler.h>
+#include <linux/uaccess.h>
+
 #include <asm/processor.h>
 #include <asm/ucontext.h>
-#include <asm/uaccess.h>
 #include <asm/i387.h>
 #include <asm/proto.h>
 #include <asm/ia32_unistd.h>
 #include <asm/mce.h>
+#include <asm/syscall.h>
+#include <asm/syscalls.h>
 #include "sigframe.h"
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 # define FIX_EFLAGS    __FIX_EFLAGS
 #endif
 
-int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
-               sigset_t *set, struct pt_regs * regs); 
-int ia32_setup_frame(int sig, struct k_sigaction *ka,
-            sigset_t *set, struct pt_regs * regs); 
-
 asmlinkage long
 sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
                struct pt_regs *regs)
@@ -128,7 +127,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
        /* Always make any pending restarted system calls return -EINTR */
        current_thread_info()->restart_block.fn = do_no_restart_syscall;
 
-#define COPY(x)                err |= __get_user(regs->x, &sc->x)
+#define COPY(x)                (err |= __get_user(regs->x, &sc->x))
 
        COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
        COPY(dx); COPY(cx); COPY(ip);
@@ -158,7 +157,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
        }
 
        {
-               struct _fpstate __user * buf;
+               struct _fpstate __user *buf;
                err |= __get_user(buf, &sc->fpstate);
 
                if (buf) {
@@ -198,7 +197,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
        current->blocked = set;
        recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
-       
+
        if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
                goto badframe;
 
@@ -208,16 +207,17 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
        return ax;
 
 badframe:
-       signal_fault(regs,frame,"sigreturn");
+       signal_fault(regs, frame, "sigreturn");
        return 0;
-}      
+}
 
 /*
  * Set up a signal frame.
  */
 
 static inline int
-setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, unsigned long mask, struct task_struct *me)
+setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
+               unsigned long mask, struct task_struct *me)
 {
        int err = 0;
 
@@ -273,35 +273,35 @@ get_stack(struct k_sigaction *ka, struct pt_regs *regs, unsigned long size)
 }
 
 static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
-                          sigset_t *set, struct pt_regs * regs)
+                          sigset_t *set, struct pt_regs *regs)
 {
        struct rt_sigframe __user *frame;
-       struct _fpstate __user *fp = NULL; 
+       struct _fpstate __user *fp = NULL;
        int err = 0;
        struct task_struct *me = current;
 
        if (used_math()) {
-               fp = get_stack(ka, regs, sizeof(struct _fpstate)); 
+               fp = get_stack(ka, regs, sizeof(struct _fpstate));
                frame = (void __user *)round_down(
                        (unsigned long)fp - sizeof(struct rt_sigframe), 16) - 8;
 
                if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate)))
                        goto give_sigsegv;
 
-               if (save_i387(fp) < 0) 
-                       err |= -1; 
+               if (save_i387(fp) < 0)
+                       err |= -1;
        } else
                frame = get_stack(ka, regs, sizeof(struct rt_sigframe)) - 8;
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
                goto give_sigsegv;
 
-       if (ka->sa.sa_flags & SA_SIGINFO) { 
+       if (ka->sa.sa_flags & SA_SIGINFO) {
                err |= copy_siginfo_to_user(&frame->info, info);
                if (err)
                        goto give_sigsegv;
        }
-               
+
        /* Create the ucontext.  */
        err |= __put_user(0, &frame->uc.uc_flags);
        err |= __put_user(0, &frame->uc.uc_link);
@@ -311,9 +311,9 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size);
        err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me);
        err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
-       if (sizeof(*set) == 16) { 
+       if (sizeof(*set) == 16) {
                __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
-               __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]); 
+               __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
        } else
                err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
 
@@ -324,7 +324,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
        } else {
                /* could use a vstub here */
-               goto give_sigsegv; 
+               goto give_sigsegv;
        }
 
        if (err)
@@ -332,7 +332,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 
        /* Set up registers for signal handler */
        regs->di = sig;
-       /* In case the signal handler was declared without prototypes */ 
+       /* In case the signal handler was declared without prototypes */
        regs->ax = 0;
 
        /* This also works for non SA_SIGINFO handlers because they expect the
@@ -354,38 +354,9 @@ give_sigsegv:
        return -EFAULT;
 }
 
-/*
- * Return -1L or the syscall number that @regs is executing.
- */
-static long current_syscall(struct pt_regs *regs)
-{
-       /*
-        * We always sign-extend a -1 value being set here,
-        * so this is always either -1L or a syscall number.
-        */
-       return regs->orig_ax;
-}
-
-/*
- * Return a value that is -EFOO if the system call in @regs->orig_ax
- * returned an error.  This only works for @regs from @current.
- */
-static long current_syscall_ret(struct pt_regs *regs)
-{
-#ifdef CONFIG_IA32_EMULATION
-       if (test_thread_flag(TIF_IA32))
-               /*
-                * Sign-extend the value so (int)-EFOO becomes (long)-EFOO
-                * and will match correctly in comparisons.
-                */
-               return (int) regs->ax;
-#endif
-       return regs->ax;
-}
-
 /*
  * OK, we're invoking a handler
- */    
+ */
 
 static int
 handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
@@ -394,9 +365,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
        int ret;
 
        /* Are we from a system call? */
-       if (current_syscall(regs) >= 0) {
+       if (syscall_get_nr(current, regs) >= 0) {
                /* If so, check system call restarting.. */
-               switch (current_syscall_ret(regs)) {
+               switch (syscall_get_error(current, regs)) {
                case -ERESTART_RESTARTBLOCK:
                case -ERESTARTNOHAND:
                        regs->ax = -EINTR;
@@ -429,7 +400,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
                        ret = ia32_setup_rt_frame(sig, ka, info, oldset, regs);
                else
                        ret = ia32_setup_frame(sig, ka, oldset, regs);
-       } else 
+       } else
 #endif
        ret = setup_rt_frame(sig, ka, info, oldset, regs);
 
@@ -453,15 +424,16 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
                 * handler too.
                 */
                regs->flags &= ~X86_EFLAGS_TF;
-               if (test_thread_flag(TIF_SINGLESTEP))
-                       ptrace_notify(SIGTRAP);
 
                spin_lock_irq(&current->sighand->siglock);
-               sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+               sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
                if (!(ka->sa.sa_flags & SA_NODEFER))
-                       sigaddset(&current->blocked,sig);
+                       sigaddset(&current->blocked, sig);
                recalc_sigpending();
                spin_unlock_irq(&current->sighand->siglock);
+
+               tracehook_signal_handler(sig, info, ka, regs,
+                                        test_thread_flag(TIF_SINGLESTEP));
        }
 
        return ret;
@@ -518,9 +490,9 @@ static void do_signal(struct pt_regs *regs)
        }
 
        /* Did we come from a system call? */
-       if (current_syscall(regs) >= 0) {
+       if (syscall_get_nr(current, regs) >= 0) {
                /* Restart the system call - no handlers present */
-               switch (current_syscall_ret(regs)) {
+               switch (syscall_get_error(current, regs)) {
                case -ERESTARTNOHAND:
                case -ERESTARTSYS:
                case -ERESTARTNOINTR:
@@ -558,17 +530,23 @@ void do_notify_resume(struct pt_regs *regs, void *unused,
        /* deal with pending signal delivery */
        if (thread_info_flags & _TIF_SIGPENDING)
                do_signal(regs);
+
+       if (thread_info_flags & _TIF_NOTIFY_RESUME) {
+               clear_thread_flag(TIF_NOTIFY_RESUME);
+               tracehook_notify_resume(regs);
+       }
 }
 
 void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
-{ 
-       struct task_struct *me = current; 
+{
+       struct task_struct *me = current;
        if (show_unhandled_signals && printk_ratelimit()) {
                printk("%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx",
-              me->comm,me->pid,where,frame,regs->ip,regs->sp,regs->orig_ax);
+              me->comm, me->pid, where, frame, regs->ip,
+                  regs->sp, regs->orig_ax);
                print_vma_addr(" in ", regs->ip);
                printk("\n");
        }
 
-       force_sig(SIGSEGV, me); 
-} 
+       force_sig(SIGSEGV, me);
+}
index 7985c5b3f9162ba14c0817ce25f1297b34a87a5c..4e7ccb0e2a9b01df38dd25c0561c7694e96f9649 100644 (file)
@@ -88,7 +88,7 @@ static DEFINE_PER_CPU(struct task_struct *, idle_thread_array);
 #define get_idle_for_cpu(x)      (per_cpu(idle_thread_array, x))
 #define set_idle_for_cpu(x, p)   (per_cpu(idle_thread_array, x) = (p))
 #else
-struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ;
+static struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ;
 #define get_idle_for_cpu(x)      (idle_thread_array[(x)])
 #define set_idle_for_cpu(x, p)   (idle_thread_array[(x)] = (p))
 #endif
@@ -129,7 +129,7 @@ static int boot_cpu_logical_apicid;
 static cpumask_t cpu_sibling_setup_map;
 
 /* Set if we find a B stepping CPU */
-int __cpuinitdata smp_b_stepping;
+static int __cpuinitdata smp_b_stepping;
 
 #if defined(CONFIG_NUMA) && defined(CONFIG_X86_32)
 
@@ -257,6 +257,7 @@ static void __cpuinit smp_callin(void)
        end_local_APIC_setup();
        map_cpu_to_logical_apicid();
 
+       notify_cpu_starting(cpuid);
        /*
         * Get our bogomips.
         *
@@ -1313,16 +1314,13 @@ __init void prefill_possible_map(void)
        if (!num_processors)
                num_processors = 1;
 
-#ifdef CONFIG_HOTPLUG_CPU
        if (additional_cpus == -1) {
                if (disabled_cpus > 0)
                        additional_cpus = disabled_cpus;
                else
                        additional_cpus = 0;
        }
-#else
-       additional_cpus = 0;
-#endif
+
        possible = num_processors + additional_cpus;
        if (possible > NR_CPUS)
                possible = NR_CPUS;
index 7066cb855a60154ea077f855b704bb40c0d58a53..1884a8d12bfaf130d99d7f9602268c5a7048271d 100644 (file)
@@ -22,6 +22,8 @@
 #include <linux/uaccess.h>
 #include <linux/unistd.h>
 
+#include <asm/syscalls.h>
+
 asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
                          unsigned long prot, unsigned long flags,
                          unsigned long fd, unsigned long pgoff)
index 3b360ef33817c9b618e661f452e682a43dfe91bc..6bc211accf087ed2be1a381395eae95093f4dbf4 100644 (file)
 #include <linux/utsname.h>
 #include <linux/personality.h>
 #include <linux/random.h>
+#include <linux/uaccess.h>
 
-#include <asm/uaccess.h>
 #include <asm/ia32.h>
+#include <asm/syscalls.h>
 
-asmlinkage long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
-       unsigned long fd, unsigned long off)
+asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
+               unsigned long prot, unsigned long flags,
+               unsigned long fd, unsigned long off)
 {
        long error;
-       struct file * file;
+       struct file *file;
 
        error = -EINVAL;
        if (off & ~PAGE_MASK)
@@ -56,9 +58,9 @@ static void find_start_end(unsigned long flags, unsigned long *begin,
                   unmapped base down for this case. This can give
                   conflicts with the heap, but we assume that glibc
                   malloc knows how to fall back to mmap. Give it 1GB
-                  of playground for now. -AK */ 
-               *begin = 0x40000000; 
-               *end = 0x80000000;              
+                  of playground for now. -AK */
+               *begin = 0x40000000;
+               *end = 0x80000000;
                if (current->flags & PF_RANDOMIZE) {
                        new_begin = randomize_range(*begin, *begin + 0x02000000, 0);
                        if (new_begin)
@@ -66,9 +68,9 @@ static void find_start_end(unsigned long flags, unsigned long *begin,
                }
        } else {
                *begin = TASK_UNMAPPED_BASE;
-               *end = TASK_SIZE; 
+               *end = TASK_SIZE;
        }
-} 
+}
 
 unsigned long
 arch_get_unmapped_area(struct file *filp, unsigned long addr,
@@ -78,11 +80,11 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
        struct vm_area_struct *vma;
        unsigned long start_addr;
        unsigned long begin, end;
-       
+
        if (flags & MAP_FIXED)
                return addr;
 
-       find_start_end(flags, &begin, &end); 
+       find_start_end(flags, &begin, &end);
 
        if (len > end)
                return -ENOMEM;
@@ -96,12 +98,12 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
        }
        if (((flags & MAP_32BIT) || test_thread_flag(TIF_IA32))
            && len <= mm->cached_hole_size) {
-               mm->cached_hole_size = 0;
+               mm->cached_hole_size = 0;
                mm->free_area_cache = begin;
        }
        addr = mm->free_area_cache;
-       if (addr < begin) 
-               addr = begin; 
+       if (addr < begin)
+               addr = begin;
        start_addr = addr;
 
 full_search:
@@ -127,7 +129,7 @@ full_search:
                        return addr;
                }
                if (addr + mm->cached_hole_size < vma->vm_start)
-                       mm->cached_hole_size = vma->vm_start - addr;
+                       mm->cached_hole_size = vma->vm_start - addr;
 
                addr = vma->vm_end;
        }
@@ -177,7 +179,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
                vma = find_vma(mm, addr-len);
                if (!vma || addr <= vma->vm_start)
                        /* remember the address as a hint for next time */
-                       return (mm->free_area_cache = addr-len);
+                       return mm->free_area_cache = addr-len;
        }
 
        if (mm->mmap_base < len)
@@ -194,7 +196,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
                vma = find_vma(mm, addr);
                if (!vma || addr+len <= vma->vm_start)
                        /* remember the address as a hint for next time */
-                       return (mm->free_area_cache = addr);
+                       return mm->free_area_cache = addr;
 
                /* remember the largest hole we saw so far */
                if (addr + mm->cached_hole_size < vma->vm_start)
@@ -224,13 +226,13 @@ bottomup:
 }
 
 
-asmlinkage long sys_uname(struct new_utsname __user * name)
+asmlinkage long sys_uname(struct new_utsname __user *name)
 {
        int err;
        down_read(&uts_sem);
-       err = copy_to_user(name, utsname(), sizeof (*name));
+       err = copy_to_user(name, utsname(), sizeof(*name));
        up_read(&uts_sem);
-       if (personality(current->personality) == PER_LINUX32) 
-               err |= copy_to_user(&name->machine, "i686", 5);                 
+       if (personality(current->personality) == PER_LINUX32)
+               err |= copy_to_user(&name->machine, "i686", 5);
        return err ? -EFAULT : 0;
 }
index 170d43c174878ac14b15185affa0a60599e290e2..3d1be4f0fac563f56247204e8d62967872092268 100644 (file)
@@ -8,12 +8,12 @@
 #define __NO_STUBS
 
 #define __SYSCALL(nr, sym) extern asmlinkage void sym(void) ;
-#undef _ASM_X86_64_UNISTD_H_
+#undef ASM_X86__UNISTD_64_H
 #include <asm/unistd_64.h>
 
 #undef __SYSCALL
 #define __SYSCALL(nr, sym) [nr] = sym,
-#undef _ASM_X86_64_UNISTD_H_
+#undef ASM_X86__UNISTD_64_H
 
 typedef void (*sys_call_ptr_t)(void);
 
index ffe3c664afc0aae1318c1b26ab272f858d87812b..bbecf8b6bf96392de71968bdfd5da4b8aae006ad 100644 (file)
@@ -36,6 +36,7 @@
 #include <asm/arch_hooks.h>
 #include <asm/hpet.h>
 #include <asm/time.h>
+#include <asm/timer.h>
 
 #include "do_timer.h"
 
index ab6bf375a3077e0e6052f07bff9c5c6a93742e45..6bb7b8579e70e0a73a67ddcb9f69c01696bb6413 100644 (file)
@@ -10,6 +10,7 @@
 #include <asm/ldt.h>
 #include <asm/processor.h>
 #include <asm/proto.h>
+#include <asm/syscalls.h>
 
 #include "tls.h"
 
index 513caaca7115eecf5d7a58de7cf12fbe9e60e6e4..7a31f104bef9136538a304715557480243022655 100644 (file)
@@ -32,6 +32,8 @@
 #include <linux/bug.h>
 #include <linux/nmi.h>
 #include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/io.h>
 
 #if defined(CONFIG_EDAC)
 #include <linux/edac.h>
@@ -45,9 +47,6 @@
 #include <asm/unwind.h>
 #include <asm/desc.h>
 #include <asm/i387.h>
-#include <asm/nmi.h>
-#include <asm/smp.h>
-#include <asm/io.h>
 #include <asm/pgalloc.h>
 #include <asm/proto.h>
 #include <asm/pda.h>
@@ -85,7 +84,8 @@ static inline void preempt_conditional_cli(struct pt_regs *regs)
 
 void printk_address(unsigned long address, int reliable)
 {
-       printk(" [<%016lx>] %s%pS\n", address, reliable ? "": "? ", (void *) address);
+       printk(" [<%016lx>] %s%pS\n",
+                       address, reliable ?     "" : "? ", (void *) address);
 }
 
 static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
@@ -98,7 +98,8 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
                [STACKFAULT_STACK - 1] = "#SS",
                [MCE_STACK - 1] = "#MC",
 #if DEBUG_STKSZ > EXCEPTION_STKSZ
-               [N_EXCEPTION_STACKS ... N_EXCEPTION_STACKS + DEBUG_STKSZ / EXCEPTION_STKSZ - 2] = "#DB[?]"
+               [N_EXCEPTION_STACKS ...
+                       N_EXCEPTION_STACKS + DEBUG_STKSZ / EXCEPTION_STKSZ - 2] = "#DB[?]"
 #endif
        };
        unsigned k;
@@ -163,7 +164,7 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
 }
 
 /*
- * x86-64 can have up to three kernel stacks: 
+ * x86-64 can have up to three kernel stacks:
  * process stack
  * interrupt stack
  * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack
@@ -219,7 +220,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
                const struct stacktrace_ops *ops, void *data)
 {
        const unsigned cpu = get_cpu();
-       unsigned long *irqstack_end = (unsigned long*)cpu_pda(cpu)->irqstackptr;
+       unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr;
        unsigned used = 0;
        struct thread_info *tinfo;
 
@@ -237,7 +238,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
        if (!bp) {
                if (task == current) {
                        /* Grab bp right from our regs */
-                       asm("movq %%rbp, %0" : "=r" (bp) :);
+                       asm("movq %%rbp, %0" : "=r" (bp) : );
                } else {
                        /* bp is the last reg pushed by switch_to */
                        bp = *(unsigned long *) task->thread.sp;
@@ -339,9 +340,8 @@ static void
 show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
                unsigned long *stack, unsigned long bp, char *log_lvl)
 {
-       printk("\nCall Trace:\n");
+       printk("Call Trace:\n");
        dump_trace(task, regs, stack, bp, &print_trace_ops, log_lvl);
-       printk("\n");
 }
 
 void show_trace(struct task_struct *task, struct pt_regs *regs,
@@ -357,11 +357,15 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
        unsigned long *stack;
        int i;
        const int cpu = smp_processor_id();
-       unsigned long *irqstack_end = (unsigned long *) (cpu_pda(cpu)->irqstackptr);
-       unsigned long *irqstack = (unsigned long *) (cpu_pda(cpu)->irqstackptr - IRQSTACKSIZE);
+       unsigned long *irqstack_end =
+               (unsigned long *) (cpu_pda(cpu)->irqstackptr);
+       unsigned long *irqstack =
+               (unsigned long *) (cpu_pda(cpu)->irqstackptr - IRQSTACKSIZE);
 
-       // debugging aid: "show_stack(NULL, NULL);" prints the
-       // back trace for this cpu.
+       /*
+        * debugging aid: "show_stack(NULL, NULL);" prints the
+        * back trace for this cpu.
+        */
 
        if (sp == NULL) {
                if (task)
@@ -386,6 +390,7 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
                printk(" %016lx", *stack++);
                touch_nmi_watchdog();
        }
+       printk("\n");
        show_trace_log_lvl(task, regs, sp, bp, log_lvl);
 }
 
@@ -404,7 +409,7 @@ void dump_stack(void)
 
 #ifdef CONFIG_FRAME_POINTER
        if (!bp)
-               asm("movq %%rbp, %0" : "=r" (bp):);
+               asm("movq %%rbp, %0" : "=r" (bp) : );
 #endif
 
        printk("Pid: %d, comm: %.20s %s %s %.*s\n",
@@ -414,7 +419,6 @@ void dump_stack(void)
                init_utsname()->version);
        show_trace(NULL, NULL, &stack, bp);
 }
-
 EXPORT_SYMBOL(dump_stack);
 
 void show_registers(struct pt_regs *regs)
@@ -443,7 +447,6 @@ void show_registers(struct pt_regs *regs)
                printk("Stack: ");
                show_stack_log_lvl(NULL, regs, (unsigned long *)sp,
                                regs->bp, "");
-               printk("\n");
 
                printk(KERN_EMERG "Code: ");
 
@@ -493,7 +496,7 @@ unsigned __kprobes long oops_begin(void)
        raw_local_irq_save(flags);
        cpu = smp_processor_id();
        if (!__raw_spin_trylock(&die_lock)) {
-               if (cpu == die_owner) 
+               if (cpu == die_owner)
                        /* nested oops. should stop eventually */;
                else
                        __raw_spin_lock(&die_lock);
@@ -638,7 +641,7 @@ kernel_trap:
 }
 
 #define DO_ERROR(trapnr, signr, str, name) \
-asmlinkage void do_##name(struct pt_regs * regs, long error_code)      \
+asmlinkage void do_##name(struct pt_regs *regs, long error_code)       \
 {                                                                      \
        if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr)  \
                                                        == NOTIFY_STOP) \
@@ -648,7 +651,7 @@ asmlinkage void do_##name(struct pt_regs * regs, long error_code)   \
 }
 
 #define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr)                \
-asmlinkage void do_##name(struct pt_regs * regs, long error_code)      \
+asmlinkage void do_##name(struct pt_regs *regs, long error_code)       \
 {                                                                      \
        siginfo_t info;                                                 \
        info.si_signo = signr;                                          \
@@ -683,7 +686,7 @@ asmlinkage void do_stack_segment(struct pt_regs *regs, long error_code)
        preempt_conditional_cli(regs);
 }
 
-asmlinkage void do_double_fault(struct pt_regs * regs, long error_code)
+asmlinkage void do_double_fault(struct pt_regs *regs, long error_code)
 {
        static const char str[] = "double fault";
        struct task_struct *tsk = current;
@@ -778,9 +781,10 @@ io_check_error(unsigned char reason, struct pt_regs *regs)
 }
 
 static notrace __kprobes void
-unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
+unknown_nmi_error(unsigned char reason, struct pt_regs *regs)
 {
-       if (notify_die(DIE_NMIUNKNOWN, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP)
+       if (notify_die(DIE_NMIUNKNOWN, "nmi", regs, reason, 2, SIGINT) ==
+                       NOTIFY_STOP)
                return;
        printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x.\n",
                reason);
@@ -882,7 +886,7 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs)
        else if (user_mode(eregs))
                regs = task_pt_regs(current);
        /* Exception from kernel and interrupts are enabled. Move to
-          kernel process stack. */
+          kernel process stack. */
        else if (eregs->flags & X86_EFLAGS_IF)
                regs = (struct pt_regs *)(eregs->sp -= sizeof(struct pt_regs));
        if (eregs != regs)
@@ -891,7 +895,7 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs)
 }
 
 /* runs on IST stack. */
-asmlinkage void __kprobes do_debug(struct pt_regs * regs,
+asmlinkage void __kprobes do_debug(struct pt_regs *regs,
                                   unsigned long error_code)
 {
        struct task_struct *tsk = current;
@@ -1035,7 +1039,7 @@ asmlinkage void do_coprocessor_error(struct pt_regs *regs)
 
 asmlinkage void bad_intr(void)
 {
-       printk("bad interrupt"); 
+       printk("bad interrupt");
 }
 
 asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs)
@@ -1047,7 +1051,7 @@ asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs)
 
        conditional_sti(regs);
        if (!user_mode(regs) &&
-               kernel_math_error(regs, "kernel simd math error", 19))
+                       kernel_math_error(regs, "kernel simd math error", 19))
                return;
 
        /*
@@ -1092,7 +1096,7 @@ asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs)
        force_sig_info(SIGFPE, &info, task);
 }
 
-asmlinkage void do_spurious_interrupt_bug(struct pt_regs * regs)
+asmlinkage void do_spurious_interrupt_bug(struct pt_regs *regs)
 {
 }
 
@@ -1149,8 +1153,10 @@ void __init trap_init(void)
        set_intr_gate(0, &divide_error);
        set_intr_gate_ist(1, &debug, DEBUG_STACK);
        set_intr_gate_ist(2, &nmi, NMI_STACK);
-       set_system_gate_ist(3, &int3, DEBUG_STACK); /* int3 can be called from all */
-       set_system_gate(4, &overflow); /* int4 can be called from all */
+       /* int3 can be called from all */
+       set_system_gate_ist(3, &int3, DEBUG_STACK);
+       /* int4 can be called from all */
+       set_system_gate(4, &overflow);
        set_intr_gate(5, &bounds);
        set_intr_gate(6, &invalid_op);
        set_intr_gate(7, &device_not_available);
index 8f98e9de1b82f5f6a13015bd34fe428187e79c38..161bb850fc475b074524cfbba13fc161a4e6a439 100644 (file)
@@ -104,7 +104,7 @@ __setup("notsc", notsc_setup);
 /*
  * Read TSC and the reference counters. Take care of SMI disturbance
  */
-static u64 tsc_read_refs(u64 *pm, u64 *hpet)
+static u64 tsc_read_refs(u64 *p, int hpet)
 {
        u64 t1, t2;
        int i;
@@ -112,9 +112,9 @@ static u64 tsc_read_refs(u64 *pm, u64 *hpet)
        for (i = 0; i < MAX_RETRIES; i++) {
                t1 = get_cycles();
                if (hpet)
-                       *hpet = hpet_readl(HPET_COUNTER) & 0xFFFFFFFF;
+                       *p = hpet_readl(HPET_COUNTER) & 0xFFFFFFFF;
                else
-                       *pm = acpi_pm_read_early();
+                       *p = acpi_pm_read_early();
                t2 = get_cycles();
                if ((t2 - t1) < SMI_TRESHOLD)
                        return t2;
@@ -122,6 +122,52 @@ static u64 tsc_read_refs(u64 *pm, u64 *hpet)
        return ULLONG_MAX;
 }
 
+/*
+ * Calculate the TSC frequency from HPET reference
+ */
+static unsigned long calc_hpet_ref(u64 deltatsc, u64 hpet1, u64 hpet2)
+{
+       u64 tmp;
+
+       if (hpet2 < hpet1)
+               hpet2 += 0x100000000ULL;
+       hpet2 -= hpet1;
+       tmp = ((u64)hpet2 * hpet_readl(HPET_PERIOD));
+       do_div(tmp, 1000000);
+       do_div(deltatsc, tmp);
+
+       return (unsigned long) deltatsc;
+}
+
+/*
+ * Calculate the TSC frequency from PMTimer reference
+ */
+static unsigned long calc_pmtimer_ref(u64 deltatsc, u64 pm1, u64 pm2)
+{
+       u64 tmp;
+
+       if (!pm1 && !pm2)
+               return ULONG_MAX;
+
+       if (pm2 < pm1)
+               pm2 += (u64)ACPI_PM_OVRRUN;
+       pm2 -= pm1;
+       tmp = pm2 * 1000000000LL;
+       do_div(tmp, PMTMR_TICKS_PER_SEC);
+       do_div(deltatsc, tmp);
+
+       return (unsigned long) deltatsc;
+}
+
+#define CAL_MS         10
+#define CAL_LATCH      (CLOCK_TICK_RATE / (1000 / CAL_MS))
+#define CAL_PIT_LOOPS  1000
+
+#define CAL2_MS                50
+#define CAL2_LATCH     (CLOCK_TICK_RATE / (1000 / CAL2_MS))
+#define CAL2_PIT_LOOPS 5000
+
+
 /*
  * Try to calibrate the TSC against the Programmable
  * Interrupt Timer and return the frequency of the TSC
@@ -129,7 +175,7 @@ static u64 tsc_read_refs(u64 *pm, u64 *hpet)
  *
  * Return ULONG_MAX on failure to calibrate.
  */
-static unsigned long pit_calibrate_tsc(void)
+static unsigned long pit_calibrate_tsc(u32 latch, unsigned long ms, int loopmin)
 {
        u64 tsc, t1, t2, delta;
        unsigned long tscmin, tscmax;
@@ -144,8 +190,8 @@ static unsigned long pit_calibrate_tsc(void)
         * (LSB then MSB) to begin countdown.
         */
        outb(0xb0, 0x43);
-       outb((CLOCK_TICK_RATE / (1000 / 50)) & 0xff, 0x42);
-       outb((CLOCK_TICK_RATE / (1000 / 50)) >> 8, 0x42);
+       outb(latch & 0xff, 0x42);
+       outb(latch >> 8, 0x42);
 
        tsc = t1 = t2 = get_cycles();
 
@@ -166,31 +212,154 @@ static unsigned long pit_calibrate_tsc(void)
        /*
         * Sanity checks:
         *
-        * If we were not able to read the PIT more than 5000
+        * If we were not able to read the PIT more than loopmin
         * times, then we have been hit by a massive SMI
         *
         * If the maximum is 10 times larger than the minimum,
         * then we got hit by an SMI as well.
         */
-       if (pitcnt < 5000 || tscmax > 10 * tscmin)
+       if (pitcnt < loopmin || tscmax > 10 * tscmin)
                return ULONG_MAX;
 
        /* Calculate the PIT value */
        delta = t2 - t1;
-       do_div(delta, 50);
+       do_div(delta, ms);
        return delta;
 }
 
+/*
+ * This reads the current MSB of the PIT counter, and
+ * checks if we are running on sufficiently fast and
+ * non-virtualized hardware.
+ *
+ * Our expectations are:
+ *
+ *  - the PIT is running at roughly 1.19MHz
+ *
+ *  - each IO is going to take about 1us on real hardware,
+ *    but we allow it to be much faster (by a factor of 10) or
+ *    _slightly_ slower (ie we allow up to a 2us read+counter
+ *    update - anything else implies a unacceptably slow CPU
+ *    or PIT for the fast calibration to work.
+ *
+ *  - with 256 PIT ticks to read the value, we have 214us to
+ *    see the same MSB (and overhead like doing a single TSC
+ *    read per MSB value etc).
+ *
+ *  - We're doing 2 reads per loop (LSB, MSB), and we expect
+ *    them each to take about a microsecond on real hardware.
+ *    So we expect a count value of around 100. But we'll be
+ *    generous, and accept anything over 50.
+ *
+ *  - if the PIT is stuck, and we see *many* more reads, we
+ *    return early (and the next caller of pit_expect_msb()
+ *    then consider it a failure when they don't see the
+ *    next expected value).
+ *
+ * These expectations mean that we know that we have seen the
+ * transition from one expected value to another with a fairly
+ * high accuracy, and we didn't miss any events. We can thus
+ * use the TSC value at the transitions to calculate a pretty
+ * good value for the TSC frequencty.
+ */
+static inline int pit_expect_msb(unsigned char val)
+{
+       int count = 0;
+
+       for (count = 0; count < 50000; count++) {
+               /* Ignore LSB */
+               inb(0x42);
+               if (inb(0x42) != val)
+                       break;
+       }
+       return count > 50;
+}
+
+/*
+ * How many MSB values do we want to see? We aim for a
+ * 15ms calibration, which assuming a 2us counter read
+ * error should give us roughly 150 ppm precision for
+ * the calibration.
+ */
+#define QUICK_PIT_MS 15
+#define QUICK_PIT_ITERATIONS (QUICK_PIT_MS * PIT_TICK_RATE / 1000 / 256)
+
+static unsigned long quick_pit_calibrate(void)
+{
+       /* Set the Gate high, disable speaker */
+       outb((inb(0x61) & ~0x02) | 0x01, 0x61);
+
+       /*
+        * Counter 2, mode 0 (one-shot), binary count
+        *
+        * NOTE! Mode 2 decrements by two (and then the
+        * output is flipped each time, giving the same
+        * final output frequency as a decrement-by-one),
+        * so mode 0 is much better when looking at the
+        * individual counts.
+        */
+       outb(0xb0, 0x43);
+
+       /* Start at 0xffff */
+       outb(0xff, 0x42);
+       outb(0xff, 0x42);
+
+       if (pit_expect_msb(0xff)) {
+               int i;
+               u64 t1, t2, delta;
+               unsigned char expect = 0xfe;
+
+               t1 = get_cycles();
+               for (i = 0; i < QUICK_PIT_ITERATIONS; i++, expect--) {
+                       if (!pit_expect_msb(expect))
+                               goto failed;
+               }
+               t2 = get_cycles();
+
+               /*
+                * Make sure we can rely on the second TSC timestamp:
+                */
+               if (!pit_expect_msb(expect))
+                       goto failed;
+
+               /*
+                * Ok, if we get here, then we've seen the
+                * MSB of the PIT decrement QUICK_PIT_ITERATIONS
+                * times, and each MSB had many hits, so we never
+                * had any sudden jumps.
+                *
+                * As a result, we can depend on there not being
+                * any odd delays anywhere, and the TSC reads are
+                * reliable.
+                *
+                * kHz = ticks / time-in-seconds / 1000;
+                * kHz = (t2 - t1) / (QPI * 256 / PIT_TICK_RATE) / 1000
+                * kHz = ((t2 - t1) * PIT_TICK_RATE) / (QPI * 256 * 1000)
+                */
+               delta = (t2 - t1)*PIT_TICK_RATE;
+               do_div(delta, QUICK_PIT_ITERATIONS*256*1000);
+               printk("Fast TSC calibration using PIT\n");
+               return delta;
+       }
+failed:
+       return 0;
+}
 
 /**
  * native_calibrate_tsc - calibrate the tsc on boot
  */
 unsigned long native_calibrate_tsc(void)
 {
-       u64 tsc1, tsc2, delta, pm1, pm2, hpet1, hpet2;
+       u64 tsc1, tsc2, delta, ref1, ref2;
        unsigned long tsc_pit_min = ULONG_MAX, tsc_ref_min = ULONG_MAX;
-       unsigned long flags;
-       int hpet = is_hpet_enabled(), i;
+       unsigned long flags, latch, ms, fast_calibrate;
+       int hpet = is_hpet_enabled(), i, loopmin;
+
+       local_irq_save(flags);
+       fast_calibrate = quick_pit_calibrate();
+       local_irq_restore(flags);
+       if (fast_calibrate)
+               return fast_calibrate;
 
        /*
         * Run 5 calibration loops to get the lowest frequency value
@@ -216,7 +385,13 @@ unsigned long native_calibrate_tsc(void)
         * calibration delay loop as we have to wait for a certain
         * amount of time anyway.
         */
-       for (i = 0; i < 5; i++) {
+
+       /* Preset PIT loop values */
+       latch = CAL_LATCH;
+       ms = CAL_MS;
+       loopmin = CAL_PIT_LOOPS;
+
+       for (i = 0; i < 3; i++) {
                unsigned long tsc_pit_khz;
 
                /*
@@ -226,16 +401,16 @@ unsigned long native_calibrate_tsc(void)
                 * read the end value.
                 */
                local_irq_save(flags);
-               tsc1 = tsc_read_refs(&pm1, hpet ? &hpet1 : NULL);
-               tsc_pit_khz = pit_calibrate_tsc();
-               tsc2 = tsc_read_refs(&pm2, hpet ? &hpet2 : NULL);
+               tsc1 = tsc_read_refs(&ref1, hpet);
+               tsc_pit_khz = pit_calibrate_tsc(latch, ms, loopmin);
+               tsc2 = tsc_read_refs(&ref2, hpet);
                local_irq_restore(flags);
 
                /* Pick the lowest PIT TSC calibration so far */
                tsc_pit_min = min(tsc_pit_min, tsc_pit_khz);
 
                /* hpet or pmtimer available ? */
-               if (!hpet && !pm1 && !pm2)
+               if (!hpet && !ref1 && !ref2)
                        continue;
 
                /* Check, whether the sampling was disturbed by an SMI */
@@ -243,23 +418,41 @@ unsigned long native_calibrate_tsc(void)
                        continue;
 
                tsc2 = (tsc2 - tsc1) * 1000000LL;
+               if (hpet)
+                       tsc2 = calc_hpet_ref(tsc2, ref1, ref2);
+               else
+                       tsc2 = calc_pmtimer_ref(tsc2, ref1, ref2);
 
-               if (hpet) {
-                       if (hpet2 < hpet1)
-                               hpet2 += 0x100000000ULL;
-                       hpet2 -= hpet1;
-                       tsc1 = ((u64)hpet2 * hpet_readl(HPET_PERIOD));
-                       do_div(tsc1, 1000000);
-               } else {
-                       if (pm2 < pm1)
-                               pm2 += (u64)ACPI_PM_OVRRUN;
-                       pm2 -= pm1;
-                       tsc1 = pm2 * 1000000000LL;
-                       do_div(tsc1, PMTMR_TICKS_PER_SEC);
+               tsc_ref_min = min(tsc_ref_min, (unsigned long) tsc2);
+
+               /* Check the reference deviation */
+               delta = ((u64) tsc_pit_min) * 100;
+               do_div(delta, tsc_ref_min);
+
+               /*
+                * If both calibration results are inside a 10% window
+                * then we can be sure, that the calibration
+                * succeeded. We break out of the loop right away. We
+                * use the reference value, as it is more precise.
+                */
+               if (delta >= 90 && delta <= 110) {
+                       printk(KERN_INFO
+                              "TSC: PIT calibration matches %s. %d loops\n",
+                              hpet ? "HPET" : "PMTIMER", i + 1);
+                       return tsc_ref_min;
                }
 
-               do_div(tsc2, tsc1);
-               tsc_ref_min = min(tsc_ref_min, (unsigned long) tsc2);
+               /*
+                * Check whether PIT failed more than once. This
+                * happens in virtualized environments. We need to
+                * give the virtual PC a slightly longer timeframe for
+                * the HPET/PMTIMER to make the result precise.
+                */
+               if (i == 1 && tsc_pit_min == ULONG_MAX) {
+                       latch = CAL2_LATCH;
+                       ms = CAL2_MS;
+                       loopmin = CAL2_PIT_LOOPS;
+               }
        }
 
        /*
@@ -270,7 +463,7 @@ unsigned long native_calibrate_tsc(void)
                printk(KERN_WARNING "TSC: Unable to calibrate against PIT\n");
 
                /* We don't have an alternative source, disable TSC */
-               if (!hpet && !pm1 && !pm2) {
+               if (!hpet && !ref1 && !ref2) {
                        printk("TSC: No reference (HPET/PMTIMER) available\n");
                        return 0;
                }
@@ -278,7 +471,7 @@ unsigned long native_calibrate_tsc(void)
                /* The alternative source failed as well, disable TSC */
                if (tsc_ref_min == ULONG_MAX) {
                        printk(KERN_WARNING "TSC: HPET/PMTIMER calibration "
-                              "failed due to SMI disturbance.\n");
+                              "failed.\n");
                        return 0;
                }
 
@@ -290,44 +483,25 @@ unsigned long native_calibrate_tsc(void)
        }
 
        /* We don't have an alternative source, use the PIT calibration value */
-       if (!hpet && !pm1 && !pm2) {
+       if (!hpet && !ref1 && !ref2) {
                printk(KERN_INFO "TSC: Using PIT calibration value\n");
                return tsc_pit_min;
        }
 
        /* The alternative source failed, use the PIT calibration value */
        if (tsc_ref_min == ULONG_MAX) {
-               printk(KERN_WARNING "TSC: HPET/PMTIMER calibration failed due "
-                      "to SMI disturbance. Using PIT calibration\n");
+               printk(KERN_WARNING "TSC: HPET/PMTIMER calibration failed. "
+                      "Using PIT calibration\n");
                return tsc_pit_min;
        }
 
-       /* Check the reference deviation */
-       delta = ((u64) tsc_pit_min) * 100;
-       do_div(delta, tsc_ref_min);
-
-       /*
-        * If both calibration results are inside a 5% window, the we
-        * use the lower frequency of those as it is probably the
-        * closest estimate.
-        */
-       if (delta >= 95 && delta <= 105) {
-               printk(KERN_INFO "TSC: PIT calibration confirmed by %s.\n",
-                      hpet ? "HPET" : "PMTIMER");
-               printk(KERN_INFO "TSC: using %s calibration value\n",
-                      tsc_pit_min <= tsc_ref_min ? "PIT" :
-                      hpet ? "HPET" : "PMTIMER");
-               return tsc_pit_min <= tsc_ref_min ? tsc_pit_min : tsc_ref_min;
-       }
-
-       printk(KERN_WARNING "TSC: PIT calibration deviates from %s: %lu %lu.\n",
-              hpet ? "HPET" : "PMTIMER", tsc_pit_min, tsc_ref_min);
-
        /*
         * The calibration values differ too much. In doubt, we use
         * the PIT value as we know that there are PMTIMERs around
-        * running at double speed.
+        * running at double speed. At least we let the user know:
         */
+       printk(KERN_WARNING "TSC: PIT calibration deviates from %s: %lu %lu.\n",
+              hpet ? "HPET" : "PMTIMER", tsc_pit_min, tsc_ref_min);
        printk(KERN_INFO "TSC: Using PIT calibration value\n");
        return tsc_pit_min;
 }
index 594ef47f0a639fc66d8967805acc142fec1a8ca9..61a97e616f7034e252fe1e23e8e1fc847fd476f3 100644 (file)
 #include <asm/visws/cobalt.h>
 #include <asm/visws/piix4.h>
 #include <asm/arch_hooks.h>
+#include <asm/io_apic.h>
 #include <asm/fixmap.h>
 #include <asm/reboot.h>
 #include <asm/setup.h>
 #include <asm/e820.h>
-#include <asm/smp.h>
 #include <asm/io.h>
 
 #include <mach_ipi.h>
 
 #include "mach_apic.h"
 
-#include <linux/init.h>
-#include <linux/smp.h>
-
 #include <linux/kernel_stat.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
 
-#include <asm/io.h>
-#include <asm/apic.h>
 #include <asm/i8259.h>
 #include <asm/irq_vectors.h>
-#include <asm/visws/cobalt.h>
 #include <asm/visws/lithium.h>
-#include <asm/visws/piix4.h>
 
 #include <linux/sched.h>
 #include <linux/kernel.h>
-#include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
 
 extern int no_broadcast;
 
-#include <asm/io.h>
 #include <asm/apic.h>
-#include <asm/arch_hooks.h>
-#include <asm/visws/cobalt.h>
-#include <asm/visws/lithium.h>
 
 char visws_board_type  = -1;
 char visws_board_rev   = -1;
index 38f566fa27d2b35c0e3b95382a38537745cbe53d..4eeb5cf9720d2e7b7099d145e6c87a0c771fed1a 100644 (file)
@@ -46,6 +46,7 @@
 #include <asm/io.h>
 #include <asm/tlbflush.h>
 #include <asm/irq.h>
+#include <asm/syscalls.h>
 
 /*
  * Known problems:
index edfb09f304795efea2858120d71533d1f20d5338..8c9ad02af5a2f5e8da96613d7035b7ce07d83da8 100644 (file)
@@ -393,13 +393,13 @@ static void *vmi_kmap_atomic_pte(struct page *page, enum km_type type)
 }
 #endif
 
-static void vmi_allocate_pte(struct mm_struct *mm, u32 pfn)
+static void vmi_allocate_pte(struct mm_struct *mm, unsigned long pfn)
 {
        vmi_set_page_type(pfn, VMI_PAGE_L1);
        vmi_ops.allocate_page(pfn, VMI_PAGE_L1, 0, 0, 0);
 }
 
-static void vmi_allocate_pmd(struct mm_struct *mm, u32 pfn)
+static void vmi_allocate_pmd(struct mm_struct *mm, unsigned long pfn)
 {
        /*
         * This call comes in very early, before mem_map is setup.
@@ -410,20 +410,20 @@ static void vmi_allocate_pmd(struct mm_struct *mm, u32 pfn)
        vmi_ops.allocate_page(pfn, VMI_PAGE_L2, 0, 0, 0);
 }
 
-static void vmi_allocate_pmd_clone(u32 pfn, u32 clonepfn, u32 start, u32 count)
+static void vmi_allocate_pmd_clone(unsigned long pfn, unsigned long clonepfn, unsigned long start, unsigned long count)
 {
        vmi_set_page_type(pfn, VMI_PAGE_L2 | VMI_PAGE_CLONE);
        vmi_check_page_type(clonepfn, VMI_PAGE_L2);
        vmi_ops.allocate_page(pfn, VMI_PAGE_L2 | VMI_PAGE_CLONE, clonepfn, start, count);
 }
 
-static void vmi_release_pte(u32 pfn)
+static void vmi_release_pte(unsigned long pfn)
 {
        vmi_ops.release_page(pfn, VMI_PAGE_L1);
        vmi_set_page_type(pfn, VMI_PAGE_NORMAL);
 }
 
-static void vmi_release_pmd(u32 pfn)
+static void vmi_release_pmd(unsigned long pfn)
 {
        vmi_ops.release_page(pfn, VMI_PAGE_L2);
        vmi_set_page_type(pfn, VMI_PAGE_NORMAL);
index 01b868ba82f8c21fd8384a426236e3a315f82dea..321cf720dbb637895074315967a9c49d982b14b2 100644 (file)
@@ -16,37 +16,46 @@ static void __rdmsr_on_cpu(void *info)
        rdmsr(rv->msr_no, rv->l, rv->h);
 }
 
-static void __rdmsr_safe_on_cpu(void *info)
+static void __wrmsr_on_cpu(void *info)
 {
        struct msr_info *rv = info;
 
-       rv->err = rdmsr_safe(rv->msr_no, &rv->l, &rv->h);
+       wrmsr(rv->msr_no, rv->l, rv->h);
 }
 
-static int _rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h, int safe)
+int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
 {
-       int err = 0;
+       int err;
        struct msr_info rv;
 
        rv.msr_no = msr_no;
-       if (safe) {
-               err = smp_call_function_single(cpu, __rdmsr_safe_on_cpu,
-                                              &rv, 1);
-               err = err ? err : rv.err;
-       } else {
-               err = smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1);
-       }
+       err = smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1);
        *l = rv.l;
        *h = rv.h;
 
        return err;
 }
 
-static void __wrmsr_on_cpu(void *info)
+int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
+{
+       int err;
+       struct msr_info rv;
+
+       rv.msr_no = msr_no;
+       rv.l = l;
+       rv.h = h;
+       err = smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 1);
+
+       return err;
+}
+
+/* These "safe" variants are slower and should be used when the target MSR
+   may not actually exist. */
+static void __rdmsr_safe_on_cpu(void *info)
 {
        struct msr_info *rv = info;
 
-       wrmsr(rv->msr_no, rv->l, rv->h);
+       rv->err = rdmsr_safe(rv->msr_no, &rv->l, &rv->h);
 }
 
 static void __wrmsr_safe_on_cpu(void *info)
@@ -56,45 +65,30 @@ static void __wrmsr_safe_on_cpu(void *info)
        rv->err = wrmsr_safe(rv->msr_no, rv->l, rv->h);
 }
 
-static int _wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h, int safe)
+int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
 {
-       int err = 0;
+       int err;
        struct msr_info rv;
 
        rv.msr_no = msr_no;
-       rv.l = l;
-       rv.h = h;
-       if (safe) {
-               err = smp_call_function_single(cpu, __wrmsr_safe_on_cpu,
-                                              &rv, 1);
-               err = err ? err : rv.err;
-       } else {
-               err = smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 1);
-       }
-
-       return err;
-}
+       err = smp_call_function_single(cpu, __rdmsr_safe_on_cpu, &rv, 1);
+       *l = rv.l;
+       *h = rv.h;
 
-int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
-{
-       return _wrmsr_on_cpu(cpu, msr_no, l, h, 0);
+       return err ? err : rv.err;
 }
 
-int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
-{
-       return _rdmsr_on_cpu(cpu, msr_no, l, h, 0);
-}
-
-/* These "safe" variants are slower and should be used when the target MSR
-   may not actually exist. */
 int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
 {
-       return _wrmsr_on_cpu(cpu, msr_no, l, h, 1);
-}
+       int err;
+       struct msr_info rv;
 
-int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
-{
-       return _rdmsr_on_cpu(cpu, msr_no, l, h, 1);
+       rv.msr_no = msr_no;
+       rv.l = l;
+       rv.h = h;
+       err = smp_call_function_single(cpu, __wrmsr_safe_on_cpu, &rv, 1);
+
+       return err ? err : rv.err;
 }
 
 EXPORT_SYMBOL(rdmsr_on_cpu);
index 94972e7c094df3fbbb2030c21a5490f15f5a40ca..82004d2bf05e160bfa6faf15745f38eb4ad89f46 100644 (file)
@@ -22,7 +22,7 @@ char *strcpy(char *dest, const char *src)
                "testb %%al,%%al\n\t"
                "jne 1b"
                : "=&S" (d0), "=&D" (d1), "=&a" (d2)
-               :"0" (src), "1" (dest) : "memory");
+               : "0" (src), "1" (dest) : "memory");
        return dest;
 }
 EXPORT_SYMBOL(strcpy);
@@ -42,7 +42,7 @@ char *strncpy(char *dest, const char *src, size_t count)
                "stosb\n"
                "2:"
                : "=&S" (d0), "=&D" (d1), "=&c" (d2), "=&a" (d3)
-               :"0" (src), "1" (dest), "2" (count) : "memory");
+               : "0" (src), "1" (dest), "2" (count) : "memory");
        return dest;
 }
 EXPORT_SYMBOL(strncpy);
@@ -60,7 +60,7 @@ char *strcat(char *dest, const char *src)
                "testb %%al,%%al\n\t"
                "jne 1b"
                : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
-               : "0" (src), "1" (dest), "2" (0), "3" (0xffffffffu): "memory");
+               : "0" (src), "1" (dest), "2" (0), "3" (0xffffffffu) : "memory");
        return dest;
 }
 EXPORT_SYMBOL(strcat);
@@ -105,9 +105,9 @@ int strcmp(const char *cs, const char *ct)
                "2:\tsbbl %%eax,%%eax\n\t"
                "orb $1,%%al\n"
                "3:"
-               :"=a" (res), "=&S" (d0), "=&D" (d1)
-               :"1" (cs), "2" (ct)
-               :"memory");
+               : "=a" (res), "=&S" (d0), "=&D" (d1)
+               : "1" (cs), "2" (ct)
+               : "memory");
        return res;
 }
 EXPORT_SYMBOL(strcmp);
@@ -130,9 +130,9 @@ int strncmp(const char *cs, const char *ct, size_t count)
                "3:\tsbbl %%eax,%%eax\n\t"
                "orb $1,%%al\n"
                "4:"
-               :"=a" (res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
-               :"1" (cs), "2" (ct), "3" (count)
-               :"memory");
+               : "=a" (res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
+               : "1" (cs), "2" (ct), "3" (count)
+               : "memory");
        return res;
 }
 EXPORT_SYMBOL(strncmp);
@@ -152,9 +152,9 @@ char *strchr(const char *s, int c)
                "movl $1,%1\n"
                "2:\tmovl %1,%0\n\t"
                "decl %0"
-               :"=a" (res), "=&S" (d0)
-               :"1" (s), "0" (c)
-               :"memory");
+               : "=a" (res), "=&S" (d0)
+               : "1" (s), "0" (c)
+               : "memory");
        return res;
 }
 EXPORT_SYMBOL(strchr);
@@ -169,9 +169,9 @@ size_t strlen(const char *s)
                "scasb\n\t"
                "notl %0\n\t"
                "decl %0"
-               :"=c" (res), "=&D" (d0)
-               :"1" (s), "a" (0), "0" (0xffffffffu)
-               :"memory");
+               : "=c" (res), "=&D" (d0)
+               : "1" (s), "a" (0), "0" (0xffffffffu)
+               : "memory");
        return res;
 }
 EXPORT_SYMBOL(strlen);
@@ -189,9 +189,9 @@ void *memchr(const void *cs, int c, size_t count)
                "je 1f\n\t"
                "movl $1,%0\n"
                "1:\tdecl %0"
-               :"=D" (res), "=&c" (d0)
-               :"a" (c), "0" (cs), "1" (count)
-               :"memory");
+               : "=D" (res), "=&c" (d0)
+               : "a" (c), "0" (cs), "1" (count)
+               : "memory");
        return res;
 }
 EXPORT_SYMBOL(memchr);
@@ -228,9 +228,9 @@ size_t strnlen(const char *s, size_t count)
                "cmpl $-1,%1\n\t"
                "jne 1b\n"
                "3:\tsubl %2,%0"
-               :"=a" (res), "=&d" (d0)
-               :"c" (s), "1" (count)
-               :"memory");
+               : "=a" (res), "=&d" (d0)
+               : "c" (s), "1" (count)
+               : "memory");
        return res;
 }
 EXPORT_SYMBOL(strnlen);
index 42e8a50303f32d6000416dfd08c2caec942c20f4..8e2d55f754bff8f7f221cdb96b0c01c2352f32fa 100644 (file)
@@ -23,9 +23,9 @@ __asm__ __volatile__(
        "jne 1b\n\t"
        "xorl %%eax,%%eax\n\t"
        "2:"
-       :"=a" (__res), "=&c" (d0), "=&S" (d1)
-       :"0" (0), "1" (0xffffffff), "2" (cs), "g" (ct)
-       :"dx", "di");
+       : "=a" (__res), "=&c" (d0), "=&S" (d1)
+       : "0" (0), "1" (0xffffffff), "2" (cs), "g" (ct)
+       : "dx", "di");
 return __res;
 }
 
index 3d317836be9ed9e1739e92461d0912dc37c65ffb..3f2cf11f201aaf78ca5999e20d230e36d762ffdd 100644 (file)
 #include <asm/e820.h>
 #include <asm/setup.h>
 
+#include <mach_ipi.h>
+
 #ifdef CONFIG_HOTPLUG_CPU
 #define DEFAULT_SEND_IPI       (1)
 #else
 #define DEFAULT_SEND_IPI       (0)
 #endif
 
-int no_broadcast=DEFAULT_SEND_IPI;
+int no_broadcast = DEFAULT_SEND_IPI;
 
 /**
  * pre_intr_init_hook - initialisation prior to setting up interrupt vectors
index ee0fba0921572ba89ad56e45e5757e9eb9351385..199a5f4a873c76b33728fbfaaf186a0fb6404530 100644 (file)
@@ -448,6 +448,8 @@ static void __init start_secondary(void *unused)
 
        VDEBUG(("VOYAGER SMP: CPU%d, stack at about %p\n", cpuid, &cpuid));
 
+       notify_cpu_starting(cpuid);
+
        /* enable interrupts */
        local_irq_enable();
 
index 62fa440678d88268ba9456150eb023c3b7f735d7..847c164725f4661c74ff52d526b46367f2ffb17e 100644 (file)
@@ -328,7 +328,7 @@ void __init initmem_init(unsigned long start_pfn,
 
        get_memcfg_numa();
 
-       kva_pages = round_up(calculate_numa_remap_pages(), PTRS_PER_PTE);
+       kva_pages = roundup(calculate_numa_remap_pages(), PTRS_PER_PTE);
 
        kva_target_pfn = round_down(max_low_pfn - kva_pages, PTRS_PER_PTE);
        do {
index a20d1fa64b4ea28f22d6c202905a71e78ce744b0..e7277cbcfb40ee1ea455fb63c4c6665656724013 100644 (file)
@@ -148,8 +148,8 @@ static void note_page(struct seq_file *m, struct pg_state *st,
         * we have now. "break" is either changing perms, levels or
         * address space marker.
         */
-       prot = pgprot_val(new_prot) & ~(PTE_PFN_MASK);
-       cur = pgprot_val(st->current_prot) & ~(PTE_PFN_MASK);
+       prot = pgprot_val(new_prot) & PTE_FLAGS_MASK;
+       cur = pgprot_val(st->current_prot) & PTE_FLAGS_MASK;
 
        if (!st->level) {
                /* First entry */
index 455f3fe67b42412c8acda3eb63e33678ebec1845..8f92cac4e6dbe226b85535b46db44259c066b3ad 100644 (file)
@@ -35,6 +35,7 @@
 #include <asm/tlbflush.h>
 #include <asm/proto.h>
 #include <asm-generic/sections.h>
+#include <asm/traps.h>
 
 /*
  * Page fault error code bits
@@ -357,8 +358,6 @@ static int is_errata100(struct pt_regs *regs, unsigned long address)
        return 0;
 }
 
-void do_invalid_op(struct pt_regs *, unsigned long);
-
 static int is_f00f_bug(struct pt_regs *regs, unsigned long address)
 {
 #ifdef CONFIG_X86_F00F_BUG
index 60ec1d08ff24b6a03917e957d707b183b1b776e6..6b9a9358b3308e9fc4972275b60f7e3b35b12d63 100644 (file)
@@ -47,6 +47,7 @@
 #include <asm/paravirt.h>
 #include <asm/setup.h>
 #include <asm/cacheflush.h>
+#include <asm/smp.h>
 
 unsigned int __VMALLOC_RESERVE = 128 << 20;
 
index d3746efb060d1602a9de63d3be955522f0cd2a5d..770536ebf7e95c6360629d1931b910b4fc2a42db 100644 (file)
@@ -225,7 +225,7 @@ void __init init_extra_mapping_uc(unsigned long phys, unsigned long size)
 void __init cleanup_highmap(void)
 {
        unsigned long vaddr = __START_KERNEL_map;
-       unsigned long end = round_up((unsigned long)_end, PMD_SIZE) - 1;
+       unsigned long end = roundup((unsigned long)_end, PMD_SIZE) - 1;
        pmd_t *pmd = level2_kernel_pgt;
        pmd_t *last_pmd = pmd + PTRS_PER_PMD;
 
@@ -451,14 +451,14 @@ static void __init find_early_table_space(unsigned long end)
        unsigned long puds, pmds, ptes, tables, start;
 
        puds = (end + PUD_SIZE - 1) >> PUD_SHIFT;
-       tables = round_up(puds * sizeof(pud_t), PAGE_SIZE);
+       tables = roundup(puds * sizeof(pud_t), PAGE_SIZE);
        if (direct_gbpages) {
                unsigned long extra;
                extra = end - ((end>>PUD_SHIFT) << PUD_SHIFT);
                pmds = (extra + PMD_SIZE - 1) >> PMD_SHIFT;
        } else
                pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT;
-       tables += round_up(pmds * sizeof(pmd_t), PAGE_SIZE);
+       tables += roundup(pmds * sizeof(pmd_t), PAGE_SIZE);
 
        if (cpu_has_pse) {
                unsigned long extra;
@@ -466,7 +466,7 @@ static void __init find_early_table_space(unsigned long end)
                ptes = (extra + PAGE_SIZE - 1) >> PAGE_SHIFT;
        } else
                ptes = (end + PAGE_SIZE - 1) >> PAGE_SHIFT;
-       tables += round_up(ptes * sizeof(pte_t), PAGE_SIZE);
+       tables += roundup(ptes * sizeof(pte_t), PAGE_SIZE);
 
        /*
         * RED-PEN putting page tables only on node 0 could
index d4b6e6a29ae3597c45071805f734a502a12d6ab2..cac6da54203bfdee878d61c2debb71104ce4f0b6 100644 (file)
@@ -421,7 +421,7 @@ void unxlate_dev_mem_ptr(unsigned long phys, void *addr)
        return;
 }
 
-int __initdata early_ioremap_debug;
+static int __initdata early_ioremap_debug;
 
 static int __init early_ioremap_debug_setup(char *str)
 {
@@ -547,7 +547,7 @@ static inline void __init early_clear_fixmap(enum fixed_addresses idx)
 }
 
 
-int __initdata early_ioremap_nested;
+static int __initdata early_ioremap_nested;
 
 static int __init check_early_ioremap_leak(void)
 {
index a4dd793d6003e6074e12d40441bd2dcb524297ee..cebcbf152d46b06b725b525debc573f3d91da71e 100644 (file)
@@ -79,7 +79,7 @@ static int __init allocate_cachealigned_memnodemap(void)
                return 0;
 
        addr = 0x8000;
-       nodemap_size = round_up(sizeof(s16) * memnodemapsize, L1_CACHE_BYTES);
+       nodemap_size = roundup(sizeof(s16) * memnodemapsize, L1_CACHE_BYTES);
        nodemap_addr = find_e820_area(addr, max_pfn<<PAGE_SHIFT,
                                      nodemap_size, L1_CACHE_BYTES);
        if (nodemap_addr == -1UL) {
@@ -176,10 +176,10 @@ void __init setup_node_bootmem(int nodeid, unsigned long start,
        unsigned long start_pfn, last_pfn, bootmap_pages, bootmap_size;
        unsigned long bootmap_start, nodedata_phys;
        void *bootmap;
-       const int pgdat_size = round_up(sizeof(pg_data_t), PAGE_SIZE);
+       const int pgdat_size = roundup(sizeof(pg_data_t), PAGE_SIZE);
        int nid;
 
-       start = round_up(start, ZONE_ALIGN);
+       start = roundup(start, ZONE_ALIGN);
 
        printk(KERN_INFO "Bootmem setup node %d %016lx-%016lx\n", nodeid,
               start, end);
@@ -210,9 +210,9 @@ void __init setup_node_bootmem(int nodeid, unsigned long start,
        bootmap_pages = bootmem_bootmap_pages(last_pfn - start_pfn);
        nid = phys_to_nid(nodedata_phys);
        if (nid == nodeid)
-               bootmap_start = round_up(nodedata_phys + pgdat_size, PAGE_SIZE);
+               bootmap_start = roundup(nodedata_phys + pgdat_size, PAGE_SIZE);
        else
-               bootmap_start = round_up(start, PAGE_SIZE);
+               bootmap_start = roundup(start, PAGE_SIZE);
        /*
         * SMP_CACHE_BYTES could be enough, but init_bootmem_node like
         * to use that to align to PAGE_SIZE
index 43e2f8483e4f59c33559263c0011e1e5bf041f9d..898fad617abe3dd25847f0a86348d0c8d1df5150 100644 (file)
@@ -84,7 +84,7 @@ static inline unsigned long highmap_start_pfn(void)
 
 static inline unsigned long highmap_end_pfn(void)
 {
-       return __pa(round_up((unsigned long)_end, PMD_SIZE)) >> PAGE_SHIFT;
+       return __pa(roundup((unsigned long)_end, PMD_SIZE)) >> PAGE_SHIFT;
 }
 
 #endif
@@ -906,11 +906,13 @@ int set_memory_ro(unsigned long addr, int numpages)
 {
        return change_page_attr_clear(addr, numpages, __pgprot(_PAGE_RW));
 }
+EXPORT_SYMBOL_GPL(set_memory_ro);
 
 int set_memory_rw(unsigned long addr, int numpages)
 {
        return change_page_attr_set(addr, numpages, __pgprot(_PAGE_RW));
 }
+EXPORT_SYMBOL_GPL(set_memory_rw);
 
 int set_memory_np(unsigned long addr, int numpages)
 {
index d50302774fe2cf7d9796d9856b9c8515e69b5f54..86f2ffc43c3d8b7cc28d2e019f570f1ecc6128c8 100644 (file)
@@ -63,10 +63,8 @@ static inline void pgd_list_del(pgd_t *pgd)
 #define UNSHARED_PTRS_PER_PGD                          \
        (SHARED_KERNEL_PMD ? KERNEL_PGD_BOUNDARY : PTRS_PER_PGD)
 
-static void pgd_ctor(void *p)
+static void pgd_ctor(pgd_t *pgd)
 {
-       pgd_t *pgd = p;
-
        /* If the pgd points to a shared pagetable level (either the
           ptes in non-PAE, or shared PMD in PAE), then just copy the
           references from swapper_pg_dir. */
@@ -87,7 +85,7 @@ static void pgd_ctor(void *p)
                pgd_list_add(pgd);
 }
 
-static void pgd_dtor(void *pgd)
+static void pgd_dtor(pgd_t *pgd)
 {
        unsigned long flags; /* can be called from interrupt context */
 
index cab0abbd1ebe6c42a9adfb46306220a893f86541..0951db9ee5190b351a843a71a755109a6fd1586e 100644 (file)
@@ -123,7 +123,8 @@ static int __init parse_vmalloc(char *arg)
        if (!arg)
                return -EINVAL;
 
-       __VMALLOC_RESERVE = memparse(arg, &arg);
+       /* Add VMALLOC_OFFSET to the parsed value due to vm area guard hole*/
+       __VMALLOC_RESERVE = memparse(arg, &arg) + VMALLOC_OFFSET;
        return 0;
 }
 early_param("vmalloc", parse_vmalloc);
index 56b4757a1f4706cef329fac43c38e71fcd491bd6..43ac5af338d8c910c2295a7484453ab6b8a01b2a 100644 (file)
 
 #include <linux/oprofile.h>
 #include <linux/smp.h>
+#include <linux/ptrace.h>
+#include <linux/nmi.h>
 #include <asm/msr.h>
-#include <asm/ptrace.h>
 #include <asm/fixmap.h>
 #include <asm/apic.h>
-#include <asm/nmi.h>
+
 
 #include "op_x86_model.h"
 #include "op_counter.h"
@@ -40,7 +41,7 @@ static unsigned int num_controls = NUM_CONTROLS_NON_HT;
 static inline void setup_num_counters(void)
 {
 #ifdef CONFIG_SMP
-       if (smp_num_siblings == 2){
+       if (smp_num_siblings == 2) {
                num_counters = NUM_COUNTERS_HT2;
                num_controls = NUM_CONTROLS_HT2;
        }
@@ -86,7 +87,7 @@ struct p4_event_binding {
 #define CTR_FLAME_2    (1 << 6)
 #define CTR_IQ_5       (1 << 7)
 
-static struct p4_counter_binding p4_counters [NUM_COUNTERS_NON_HT] = {
+static struct p4_counter_binding p4_counters[NUM_COUNTERS_NON_HT] = {
        { CTR_BPU_0,   MSR_P4_BPU_PERFCTR0,   MSR_P4_BPU_CCCR0 },
        { CTR_MS_0,    MSR_P4_MS_PERFCTR0,    MSR_P4_MS_CCCR0 },
        { CTR_FLAME_0, MSR_P4_FLAME_PERFCTR0, MSR_P4_FLAME_CCCR0 },
@@ -97,32 +98,32 @@ static struct p4_counter_binding p4_counters [NUM_COUNTERS_NON_HT] = {
        { CTR_IQ_5,    MSR_P4_IQ_PERFCTR5,    MSR_P4_IQ_CCCR5 }
 };
 
-#define NUM_UNUSED_CCCRS       NUM_CCCRS_NON_HT - NUM_COUNTERS_NON_HT
+#define NUM_UNUSED_CCCRS (NUM_CCCRS_NON_HT - NUM_COUNTERS_NON_HT)
 
 /* p4 event codes in libop/op_event.h are indices into this table. */
 
 static struct p4_event_binding p4_events[NUM_EVENTS] = {
-       
+
        { /* BRANCH_RETIRED */
-               0x05, 0x06, 
+               0x05, 0x06,
                { {CTR_IQ_4, MSR_P4_CRU_ESCR2},
                  {CTR_IQ_5, MSR_P4_CRU_ESCR3} }
        },
-       
+
        { /* MISPRED_BRANCH_RETIRED */
-               0x04, 0x03, 
+               0x04, 0x03,
                { { CTR_IQ_4, MSR_P4_CRU_ESCR0},
                  { CTR_IQ_5, MSR_P4_CRU_ESCR1} }
        },
-       
+
        { /* TC_DELIVER_MODE */
                0x01, 0x01,
-               { { CTR_MS_0, MSR_P4_TC_ESCR0},  
+               { { CTR_MS_0, MSR_P4_TC_ESCR0},
                  { CTR_MS_2, MSR_P4_TC_ESCR1} }
        },
-       
+
        { /* BPU_FETCH_REQUEST */
-               0x00, 0x03, 
+               0x00, 0x03,
                { { CTR_BPU_0, MSR_P4_BPU_ESCR0},
                  { CTR_BPU_2, MSR_P4_BPU_ESCR1} }
        },
@@ -146,7 +147,7 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = {
        },
 
        { /* LOAD_PORT_REPLAY */
-               0x02, 0x04, 
+               0x02, 0x04,
                { { CTR_FLAME_0, MSR_P4_SAAT_ESCR0},
                  { CTR_FLAME_2, MSR_P4_SAAT_ESCR1} }
        },
@@ -170,43 +171,43 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = {
        },
 
        { /* BSQ_CACHE_REFERENCE */
-               0x07, 0x0c, 
+               0x07, 0x0c,
                { { CTR_BPU_0, MSR_P4_BSU_ESCR0},
                  { CTR_BPU_2, MSR_P4_BSU_ESCR1} }
        },
 
        { /* IOQ_ALLOCATION */
-               0x06, 0x03, 
+               0x06, 0x03,
                { { CTR_BPU_0, MSR_P4_FSB_ESCR0},
                  { 0, 0 } }
        },
 
        { /* IOQ_ACTIVE_ENTRIES */
-               0x06, 0x1a, 
+               0x06, 0x1a,
                { { CTR_BPU_2, MSR_P4_FSB_ESCR1},
                  { 0, 0 } }
        },
 
        { /* FSB_DATA_ACTIVITY */
-               0x06, 0x17, 
+               0x06, 0x17,
                { { CTR_BPU_0, MSR_P4_FSB_ESCR0},
                  { CTR_BPU_2, MSR_P4_FSB_ESCR1} }
        },
 
        { /* BSQ_ALLOCATION */
-               0x07, 0x05, 
+               0x07, 0x05,
                { { CTR_BPU_0, MSR_P4_BSU_ESCR0},
                  { 0, 0 } }
        },
 
        { /* BSQ_ACTIVE_ENTRIES */
                0x07, 0x06,
-               { { CTR_BPU_2, MSR_P4_BSU_ESCR1 /* guess */},  
+               { { CTR_BPU_2, MSR_P4_BSU_ESCR1 /* guess */},
                  { 0, 0 } }
        },
 
        { /* X87_ASSIST */
-               0x05, 0x03, 
+               0x05, 0x03,
                { { CTR_IQ_4, MSR_P4_CRU_ESCR2},
                  { CTR_IQ_5, MSR_P4_CRU_ESCR3} }
        },
@@ -216,21 +217,21 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = {
                { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
                  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
        },
-  
+
        { /* PACKED_SP_UOP */
-               0x01, 0x08, 
+               0x01, 0x08,
                { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
                  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
        },
-  
+
        { /* PACKED_DP_UOP */
-               0x01, 0x0c, 
+               0x01, 0x0c,
                { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
                  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
        },
 
        { /* SCALAR_SP_UOP */
-               0x01, 0x0a, 
+               0x01, 0x0a,
                { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
                  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
        },
@@ -242,31 +243,31 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = {
        },
 
        { /* 64BIT_MMX_UOP */
-               0x01, 0x02, 
+               0x01, 0x02,
                { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
                  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
        },
-  
+
        { /* 128BIT_MMX_UOP */
-               0x01, 0x1a, 
+               0x01, 0x1a,
                { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
                  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
        },
 
        { /* X87_FP_UOP */
-               0x01, 0x04, 
+               0x01, 0x04,
                { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
                  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
        },
-  
+
        { /* X87_SIMD_MOVES_UOP */
-               0x01, 0x2e, 
+               0x01, 0x2e,
                { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
                  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
        },
-  
+
        { /* MACHINE_CLEAR */
-               0x05, 0x02, 
+               0x05, 0x02,
                { { CTR_IQ_4, MSR_P4_CRU_ESCR2},
                  { CTR_IQ_5, MSR_P4_CRU_ESCR3} }
        },
@@ -276,9 +277,9 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = {
                { { CTR_BPU_0, MSR_P4_FSB_ESCR0},
                  { CTR_BPU_2, MSR_P4_FSB_ESCR1} }
        },
-  
+
        { /* TC_MS_XFER */
-               0x00, 0x05, 
+               0x00, 0x05,
                { { CTR_MS_0, MSR_P4_MS_ESCR0},
                  { CTR_MS_2, MSR_P4_MS_ESCR1} }
        },
@@ -308,7 +309,7 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = {
        },
 
        { /* INSTR_RETIRED */
-               0x04, 0x02, 
+               0x04, 0x02,
                { { CTR_IQ_4, MSR_P4_CRU_ESCR0},
                  { CTR_IQ_5, MSR_P4_CRU_ESCR1} }
        },
@@ -319,14 +320,14 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = {
                  { CTR_IQ_5, MSR_P4_CRU_ESCR1} }
        },
 
-       { /* UOP_TYPE */    
-               0x02, 0x02, 
+       { /* UOP_TYPE */
+               0x02, 0x02,
                { { CTR_IQ_4, MSR_P4_RAT_ESCR0},
                  { CTR_IQ_5, MSR_P4_RAT_ESCR1} }
        },
 
        { /* RETIRED_MISPRED_BRANCH_TYPE */
-               0x02, 0x05, 
+               0x02, 0x05,
                { { CTR_MS_0, MSR_P4_TBPU_ESCR0},
                  { CTR_MS_2, MSR_P4_TBPU_ESCR1} }
        },
@@ -349,8 +350,8 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = {
 #define ESCR_SET_OS_1(escr, os) ((escr) |= (((os) & 1) << 1))
 #define ESCR_SET_EVENT_SELECT(escr, sel) ((escr) |= (((sel) & 0x3f) << 25))
 #define ESCR_SET_EVENT_MASK(escr, mask) ((escr) |= (((mask) & 0xffff) << 9))
-#define ESCR_READ(escr,high,ev,i) do {rdmsr(ev->bindings[(i)].escr_address, (escr), (high));} while (0)
-#define ESCR_WRITE(escr,high,ev,i) do {wrmsr(ev->bindings[(i)].escr_address, (escr), (high));} while (0)
+#define ESCR_READ(escr, high, ev, i) do {rdmsr(ev->bindings[(i)].escr_address, (escr), (high)); } while (0)
+#define ESCR_WRITE(escr, high, ev, i) do {wrmsr(ev->bindings[(i)].escr_address, (escr), (high)); } while (0)
 
 #define CCCR_RESERVED_BITS 0x38030FFF
 #define CCCR_CLEAR(cccr) ((cccr) &= CCCR_RESERVED_BITS)
@@ -360,15 +361,15 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = {
 #define CCCR_SET_PMI_OVF_1(cccr) ((cccr) |= (1<<27))
 #define CCCR_SET_ENABLE(cccr) ((cccr) |= (1<<12))
 #define CCCR_SET_DISABLE(cccr) ((cccr) &= ~(1<<12))
-#define CCCR_READ(low, high, i) do {rdmsr(p4_counters[(i)].cccr_address, (low), (high));} while (0)
-#define CCCR_WRITE(low, high, i) do {wrmsr(p4_counters[(i)].cccr_address, (low), (high));} while (0)
+#define CCCR_READ(low, high, i) do {rdmsr(p4_counters[(i)].cccr_address, (low), (high)); } while (0)
+#define CCCR_WRITE(low, high, i) do {wrmsr(p4_counters[(i)].cccr_address, (low), (high)); } while (0)
 #define CCCR_OVF_P(cccr) ((cccr) & (1U<<31))
 #define CCCR_CLEAR_OVF(cccr) ((cccr) &= (~(1U<<31)))
 
-#define CTRL_IS_RESERVED(msrs,c) (msrs->controls[(c)].addr ? 1 : 0)
-#define CTR_IS_RESERVED(msrs,c) (msrs->counters[(c)].addr ? 1 : 0)
-#define CTR_READ(l,h,i) do {rdmsr(p4_counters[(i)].counter_address, (l), (h));} while (0)
-#define CTR_WRITE(l,i) do {wrmsr(p4_counters[(i)].counter_address, -(u32)(l), -1);} while (0)
+#define CTRL_IS_RESERVED(msrs, c) (msrs->controls[(c)].addr ? 1 : 0)
+#define CTR_IS_RESERVED(msrs, c) (msrs->counters[(c)].addr ? 1 : 0)
+#define CTR_READ(l, h, i) do {rdmsr(p4_counters[(i)].counter_address, (l), (h)); } while (0)
+#define CTR_WRITE(l, i) do {wrmsr(p4_counters[(i)].counter_address, -(u32)(l), -1); } while (0)
 #define CTR_OVERFLOW_P(ctr) (!((ctr) & 0x80000000))
 
 
@@ -380,7 +381,7 @@ static unsigned int get_stagger(void)
 #ifdef CONFIG_SMP
        int cpu = smp_processor_id();
        return (cpu != first_cpu(per_cpu(cpu_sibling_map, cpu)));
-#endif 
+#endif
        return 0;
 }
 
@@ -395,25 +396,23 @@ static unsigned long reset_value[NUM_COUNTERS_NON_HT];
 
 static void p4_fill_in_addresses(struct op_msrs * const msrs)
 {
-       unsigned int i; 
+       unsigned int i;
        unsigned int addr, cccraddr, stag;
 
        setup_num_counters();
        stag = get_stagger();
 
        /* initialize some registers */
-       for (i = 0; i < num_counters; ++i) {
+       for (i = 0; i < num_counters; ++i)
                msrs->counters[i].addr = 0;
-       }
-       for (i = 0; i < num_controls; ++i) {
+       for (i = 0; i < num_controls; ++i)
                msrs->controls[i].addr = 0;
-       }
-       
+
        /* the counter & cccr registers we pay attention to */
        for (i = 0; i < num_counters; ++i) {
                addr = p4_counters[VIRT_CTR(stag, i)].counter_address;
                cccraddr = p4_counters[VIRT_CTR(stag, i)].cccr_address;
-               if (reserve_perfctr_nmi(addr)){
+               if (reserve_perfctr_nmi(addr)) {
                        msrs->counters[i].addr = addr;
                        msrs->controls[i].addr = cccraddr;
                }
@@ -447,22 +446,22 @@ static void p4_fill_in_addresses(struct op_msrs * const msrs)
                if (reserve_evntsel_nmi(addr))
                        msrs->controls[i].addr = addr;
        }
-       
+
        for (addr = MSR_P4_MS_ESCR0 + stag;
-            addr <= MSR_P4_TC_ESCR1; ++i, addr += addr_increment()) { 
+            addr <= MSR_P4_TC_ESCR1; ++i, addr += addr_increment()) {
                if (reserve_evntsel_nmi(addr))
                        msrs->controls[i].addr = addr;
        }
-       
+
        for (addr = MSR_P4_IX_ESCR0 + stag;
-            addr <= MSR_P4_CRU_ESCR3; ++i, addr += addr_increment()) { 
+            addr <= MSR_P4_CRU_ESCR3; ++i, addr += addr_increment()) {
                if (reserve_evntsel_nmi(addr))
                        msrs->controls[i].addr = addr;
        }
 
        /* there are 2 remaining non-contiguously located ESCRs */
 
-       if (num_counters == NUM_COUNTERS_NON_HT) {              
+       if (num_counters == NUM_COUNTERS_NON_HT) {
                /* standard non-HT CPUs handle both remaining ESCRs*/
                if (reserve_evntsel_nmi(MSR_P4_CRU_ESCR5))
                        msrs->controls[i++].addr = MSR_P4_CRU_ESCR5;
@@ -498,20 +497,20 @@ static void pmc_setup_one_p4_counter(unsigned int ctr)
        unsigned int stag;
 
        stag = get_stagger();
-       
+
        /* convert from counter *number* to counter *bit* */
        counter_bit = 1 << VIRT_CTR(stag, ctr);
-       
+
        /* find our event binding structure. */
        if (counter_config[ctr].event <= 0 || counter_config[ctr].event > NUM_EVENTS) {
-               printk(KERN_ERR 
-                      "oprofile: P4 event code 0x%lx out of range\n", 
+               printk(KERN_ERR
+                      "oprofile: P4 event code 0x%lx out of range\n",
                       counter_config[ctr].event);
                return;
        }
-       
+
        ev = &(p4_events[counter_config[ctr].event - 1]);
-       
+
        for (i = 0; i < maxbind; i++) {
                if (ev->bindings[i].virt_counter & counter_bit) {
 
@@ -526,25 +525,24 @@ static void pmc_setup_one_p4_counter(unsigned int ctr)
                                ESCR_SET_OS_1(escr, counter_config[ctr].kernel);
                        }
                        ESCR_SET_EVENT_SELECT(escr, ev->event_select);
-                       ESCR_SET_EVENT_MASK(escr, counter_config[ctr].unit_mask);                       
+                       ESCR_SET_EVENT_MASK(escr, counter_config[ctr].unit_mask);
                        ESCR_WRITE(escr, high, ev, i);
-                      
+
                        /* modify CCCR */
                        CCCR_READ(cccr, high, VIRT_CTR(stag, ctr));
                        CCCR_CLEAR(cccr);
                        CCCR_SET_REQUIRED_BITS(cccr);
                        CCCR_SET_ESCR_SELECT(cccr, ev->escr_select);
-                       if (stag == 0) {
+                       if (stag == 0)
                                CCCR_SET_PMI_OVF_0(cccr);
-                       } else {
+                       else
                                CCCR_SET_PMI_OVF_1(cccr);
-                       }
                        CCCR_WRITE(cccr, high, VIRT_CTR(stag, ctr));
                        return;
                }
        }
 
-       printk(KERN_ERR 
+       printk(KERN_ERR
               "oprofile: P4 event code 0x%lx no binding, stag %d ctr %d\n",
               counter_config[ctr].event, stag, ctr);
 }
@@ -559,14 +557,14 @@ static void p4_setup_ctrs(struct op_msrs const * const msrs)
        stag = get_stagger();
 
        rdmsr(MSR_IA32_MISC_ENABLE, low, high);
-       if (! MISC_PMC_ENABLED_P(low)) {
+       if (!MISC_PMC_ENABLED_P(low)) {
                printk(KERN_ERR "oprofile: P4 PMC not available\n");
                return;
        }
 
        /* clear the cccrs we will use */
        for (i = 0 ; i < num_counters ; i++) {
-               if (unlikely(!CTRL_IS_RESERVED(msrs,i)))
+               if (unlikely(!CTRL_IS_RESERVED(msrs, i)))
                        continue;
                rdmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high);
                CCCR_CLEAR(low);
@@ -576,14 +574,14 @@ static void p4_setup_ctrs(struct op_msrs const * const msrs)
 
        /* clear all escrs (including those outside our concern) */
        for (i = num_counters; i < num_controls; i++) {
-               if (unlikely(!CTRL_IS_RESERVED(msrs,i)))
+               if (unlikely(!CTRL_IS_RESERVED(msrs, i)))
                        continue;
                wrmsr(msrs->controls[i].addr, 0, 0);
        }
 
        /* setup all counters */
        for (i = 0 ; i < num_counters ; ++i) {
-               if ((counter_config[i].enabled) && (CTRL_IS_RESERVED(msrs,i))) {
+               if ((counter_config[i].enabled) && (CTRL_IS_RESERVED(msrs, i))) {
                        reset_value[i] = counter_config[i].count;
                        pmc_setup_one_p4_counter(i);
                        CTR_WRITE(counter_config[i].count, VIRT_CTR(stag, i));
@@ -603,11 +601,11 @@ static int p4_check_ctrs(struct pt_regs * const regs,
        stag = get_stagger();
 
        for (i = 0; i < num_counters; ++i) {
-               
-               if (!reset_value[i]) 
+
+               if (!reset_value[i])
                        continue;
 
-               /* 
+               /*
                 * there is some eccentricity in the hardware which
                 * requires that we perform 2 extra corrections:
                 *
@@ -616,24 +614,24 @@ static int p4_check_ctrs(struct pt_regs * const regs,
                 *
                 * - write the counter back twice to ensure it gets
                 *   updated properly.
-                * 
+                *
                 * the former seems to be related to extra NMIs happening
                 * during the current NMI; the latter is reported as errata
                 * N15 in intel doc 249199-029, pentium 4 specification
                 * update, though their suggested work-around does not
                 * appear to solve the problem.
                 */
-               
+
                real = VIRT_CTR(stag, i);
 
                CCCR_READ(low, high, real);
-               CTR_READ(ctr, high, real);
+               CTR_READ(ctr, high, real);
                if (CCCR_OVF_P(low) || CTR_OVERFLOW_P(ctr)) {
                        oprofile_add_sample(regs, i);
-                       CTR_WRITE(reset_value[i], real);
+                       CTR_WRITE(reset_value[i], real);
                        CCCR_CLEAR_OVF(low);
                        CCCR_WRITE(low, high, real);
-                       CTR_WRITE(reset_value[i], real);
+                       CTR_WRITE(reset_value[i], real);
                }
        }
 
@@ -683,15 +681,16 @@ static void p4_shutdown(struct op_msrs const * const msrs)
        int i;
 
        for (i = 0 ; i < num_counters ; ++i) {
-               if (CTR_IS_RESERVED(msrs,i))
+               if (CTR_IS_RESERVED(msrs, i))
                        release_perfctr_nmi(msrs->counters[i].addr);
        }
-       /* some of the control registers are specially reserved in
+       /*
+        * some of the control registers are specially reserved in
         * conjunction with the counter registers (hence the starting offset).
         * This saves a few bits.
         */
        for (i = num_counters ; i < num_controls ; ++i) {
-               if (CTRL_IS_RESERVED(msrs,i))
+               if (CTRL_IS_RESERVED(msrs, i))
                        release_evntsel_nmi(msrs->controls[i].addr);
        }
 }
index 6a0fca78c36236aeedb3579a3b306f01426e15e7..22e057665e5517971a67b84a0e60e2ffe87ad151 100644 (file)
@@ -580,7 +580,7 @@ static int __cpuinit amd_cpu_notify(struct notifier_block *self,
                                    unsigned long action, void *hcpu)
 {
        int cpu = (long)hcpu;
-       switch(action) {
+       switch (action) {
        case CPU_ONLINE:
        case CPU_ONLINE_FROZEN:
                smp_call_function_single(cpu, enable_pci_io_ecs, NULL, 0);
index 8e077185e185cbc72e58be92fcbd29f05437ed23..006599db0dc7024a9bc9cde36bab97b2dc114b0f 100644 (file)
@@ -1043,35 +1043,44 @@ static void __init pcibios_fixup_irqs(void)
                if (io_apic_assign_pci_irqs) {
                        int irq;
 
-                       if (pin) {
-                               /*
-                                * interrupt pins are numbered starting
-                                * from 1
-                                */
-                               pin--;
-                               irq = IO_APIC_get_PCI_irq_vector(dev->bus->number,
-                                       PCI_SLOT(dev->devfn), pin);
-       /*
-        * Busses behind bridges are typically not listed in the MP-table.
-        * In this case we have to look up the IRQ based on the parent bus,
-        * parent slot, and pin number. The SMP code detects such bridged
-        * busses itself so we should get into this branch reliably.
-        */
-                               if (irq < 0 && dev->bus->parent) { /* go back to the bridge */
-                                       struct pci_dev *bridge = dev->bus->self;
-
-                                       pin = (pin + PCI_SLOT(dev->devfn)) % 4;
-                                       irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number,
-                                                       PCI_SLOT(bridge->devfn), pin);
-                                       if (irq >= 0)
-                                               dev_warn(&dev->dev, "using bridge %s INT %c to get IRQ %d\n",
-                                                        pci_name(bridge),
-                                                        'A' + pin, irq);
-                               }
-                               if (irq >= 0) {
-                                       dev_info(&dev->dev, "PCI->APIC IRQ transform: INT %c -> IRQ %d\n", 'A' + pin, irq);
-                                       dev->irq = irq;
-                               }
+                       if (!pin)
+                               continue;
+
+                       /*
+                        * interrupt pins are numbered starting from 1
+                        */
+                       pin--;
+                       irq = IO_APIC_get_PCI_irq_vector(dev->bus->number,
+                               PCI_SLOT(dev->devfn), pin);
+                       /*
+                        * Busses behind bridges are typically not listed in the
+                        * MP-table.  In this case we have to look up the IRQ
+                        * based on the parent bus, parent slot, and pin number.
+                        * The SMP code detects such bridged busses itself so we
+                        * should get into this branch reliably.
+                        */
+                       if (irq < 0 && dev->bus->parent) {
+                               /* go back to the bridge */
+                               struct pci_dev *bridge = dev->bus->self;
+                               int bus;
+
+                               pin = (pin + PCI_SLOT(dev->devfn)) % 4;
+                               bus = bridge->bus->number;
+                               irq = IO_APIC_get_PCI_irq_vector(bus,
+                                               PCI_SLOT(bridge->devfn), pin);
+                               if (irq >= 0)
+                                       dev_warn(&dev->dev,
+                                               "using bridge %s INT %c to "
+                                                       "get IRQ %d\n",
+                                                pci_name(bridge),
+                                                'A' + pin, irq);
+                       }
+                       if (irq >= 0) {
+                               dev_info(&dev->dev,
+                                       "PCI->APIC IRQ transform: INT %c "
+                                               "-> IRQ %d\n",
+                                       'A' + pin, irq);
+                               dev->irq = irq;
                        }
                }
 #endif
index 4fc7e872c85e4e103039f582eea5050cfc7f2f4a..d1e9b53f9d3315dce9f618c08acce0e3ded959de 100644 (file)
@@ -1,5 +1,3 @@
-.text
-
 /*
  * This may not use any stack, nor any variable that is not "NoSave":
  *
 #include <asm/segment.h>
 #include <asm/page.h>
 #include <asm/asm-offsets.h>
+#include <asm/processor-flags.h>
 
-       .text
+.text
 
 ENTRY(swsusp_arch_suspend)
-
        movl %esp, saved_context_esp
        movl %ebx, saved_context_ebx
        movl %ebp, saved_context_ebp
        movl %esi, saved_context_esi
        movl %edi, saved_context_edi
-       pushfl ; popl saved_context_eflags
+       pushfl
+       popl saved_context_eflags
 
        call swsusp_save
        ret
@@ -59,7 +58,7 @@ done:
        movl    mmu_cr4_features, %ecx
        jecxz   1f      # cr4 Pentium and higher, skip if zero
        movl    %ecx, %edx
-       andl    $~(1<<7), %edx;  # PGE
+       andl    $~(X86_CR4_PGE), %edx
        movl    %edx, %cr4;  # turn off PGE
 1:
        movl    %cr3, %eax;  # flush TLB
@@ -74,7 +73,8 @@ done:
        movl saved_context_esi, %esi
        movl saved_context_edi, %edi
 
-       pushl saved_context_eflags ; popfl
+       pushl saved_context_eflags
+       popfl
 
        xorl    %eax, %eax
 
index a4e201b47f64ec1fbaf5075da3254c6b72f109b1..7dcd321a0508729ca0d32e37525ca0d5a9d823ed 100644 (file)
@@ -812,7 +812,7 @@ static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high)
 
 /* Early in boot, while setting up the initial pagetable, assume
    everything is pinned. */
-static __init void xen_alloc_pte_init(struct mm_struct *mm, u32 pfn)
+static __init void xen_alloc_pte_init(struct mm_struct *mm, unsigned long pfn)
 {
 #ifdef CONFIG_FLATMEM
        BUG_ON(mem_map);        /* should only be used early */
@@ -822,7 +822,7 @@ static __init void xen_alloc_pte_init(struct mm_struct *mm, u32 pfn)
 
 /* Early release_pte assumes that all pts are pinned, since there's
    only init_mm and anything attached to that is pinned. */
-static void xen_release_pte_init(u32 pfn)
+static void xen_release_pte_init(unsigned long pfn)
 {
        make_lowmem_page_readwrite(__va(PFN_PHYS(pfn)));
 }
@@ -838,7 +838,7 @@ static void pin_pagetable_pfn(unsigned cmd, unsigned long pfn)
 
 /* This needs to make sure the new pte page is pinned iff its being
    attached to a pinned pagetable. */
-static void xen_alloc_ptpage(struct mm_struct *mm, u32 pfn, unsigned level)
+static void xen_alloc_ptpage(struct mm_struct *mm, unsigned long pfn, unsigned level)
 {
        struct page *page = pfn_to_page(pfn);
 
@@ -856,12 +856,12 @@ static void xen_alloc_ptpage(struct mm_struct *mm, u32 pfn, unsigned level)
        }
 }
 
-static void xen_alloc_pte(struct mm_struct *mm, u32 pfn)
+static void xen_alloc_pte(struct mm_struct *mm, unsigned long pfn)
 {
        xen_alloc_ptpage(mm, pfn, PT_PTE);
 }
 
-static void xen_alloc_pmd(struct mm_struct *mm, u32 pfn)
+static void xen_alloc_pmd(struct mm_struct *mm, unsigned long pfn)
 {
        xen_alloc_ptpage(mm, pfn, PT_PMD);
 }
@@ -909,7 +909,7 @@ static void xen_pgd_free(struct mm_struct *mm, pgd_t *pgd)
 }
 
 /* This should never happen until we're OK to use struct page */
-static void xen_release_ptpage(u32 pfn, unsigned level)
+static void xen_release_ptpage(unsigned long pfn, unsigned level)
 {
        struct page *page = pfn_to_page(pfn);
 
@@ -923,23 +923,23 @@ static void xen_release_ptpage(u32 pfn, unsigned level)
        }
 }
 
-static void xen_release_pte(u32 pfn)
+static void xen_release_pte(unsigned long pfn)
 {
        xen_release_ptpage(pfn, PT_PTE);
 }
 
-static void xen_release_pmd(u32 pfn)
+static void xen_release_pmd(unsigned long pfn)
 {
        xen_release_ptpage(pfn, PT_PMD);
 }
 
 #if PAGETABLE_LEVELS == 4
-static void xen_alloc_pud(struct mm_struct *mm, u32 pfn)
+static void xen_alloc_pud(struct mm_struct *mm, unsigned long pfn)
 {
        xen_alloc_ptpage(mm, pfn, PT_PUD);
 }
 
-static void xen_release_pud(u32 pfn)
+static void xen_release_pud(unsigned long pfn)
 {
        xen_release_ptpage(pfn, PT_PUD);
 }
index 208000b0750d28589262daaaf819d5d6ff227105..bfe73049f939925aa03136121f7a56b0914eab4d 100644 (file)
@@ -4,8 +4,8 @@
 
 obj-$(CONFIG_BLOCK) := elevator.o blk-core.o blk-tag.o blk-sysfs.o \
                        blk-barrier.o blk-settings.o blk-ioc.o blk-map.o \
-                       blk-exec.o blk-merge.o ioctl.o genhd.o scsi_ioctl.o \
-                       cmd-filter.o
+                       blk-exec.o blk-merge.o blk-softirq.o blk-timeout.o \
+                       ioctl.o genhd.o scsi_ioctl.o cmd-filter.o
 
 obj-$(CONFIG_BLK_DEV_BSG)      += bsg.o
 obj-$(CONFIG_IOSCHED_NOOP)     += noop-iosched.o
index cf4eb0eefbbf5ce9a6c13f765780149c62a1ef68..71f0abb219eee2556d41dcc9f1f1e01834b6d8aa 100644 (file)
@@ -462,7 +462,7 @@ static void as_antic_stop(struct as_data *ad)
                        del_timer(&ad->antic_timer);
                ad->antic_status = ANTIC_FINISHED;
                /* see as_work_handler */
-               kblockd_schedule_work(&ad->antic_work);
+               kblockd_schedule_work(ad->q, &ad->antic_work);
        }
 }
 
@@ -483,7 +483,7 @@ static void as_antic_timeout(unsigned long data)
                aic = ad->io_context->aic;
 
                ad->antic_status = ANTIC_FINISHED;
-               kblockd_schedule_work(&ad->antic_work);
+               kblockd_schedule_work(q, &ad->antic_work);
 
                if (aic->ttime_samples == 0) {
                        /* process anticipated on has exited or timed out*/
@@ -745,6 +745,14 @@ static int as_can_break_anticipation(struct as_data *ad, struct request *rq)
  */
 static int as_can_anticipate(struct as_data *ad, struct request *rq)
 {
+#if 0 /* disable for now, we need to check tag level as well */
+       /*
+        * SSD device without seek penalty, disable idling
+        */
+       if (blk_queue_nonrot(ad->q)) axman
+               return 0;
+#endif
+
        if (!ad->io_context)
                /*
                 * Last request submitted was a write
@@ -844,7 +852,7 @@ static void as_completed_request(struct request_queue *q, struct request *rq)
        if (ad->changed_batch && ad->nr_dispatched == 1) {
                ad->current_batch_expires = jiffies +
                                        ad->batch_expire[ad->batch_data_dir];
-               kblockd_schedule_work(&ad->antic_work);
+               kblockd_schedule_work(q, &ad->antic_work);
                ad->changed_batch = 0;
 
                if (ad->batch_data_dir == REQ_SYNC)
index a09ead19f9c5702a1ad76d709c54969176fe9e94..5c99ff8d2db8937cffb50ab1d768e52fd49ff9f3 100644 (file)
@@ -293,7 +293,7 @@ int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector)
        bio->bi_end_io = bio_end_empty_barrier;
        bio->bi_private = &wait;
        bio->bi_bdev = bdev;
-       submit_bio(1 << BIO_RW_BARRIER, bio);
+       submit_bio(WRITE_BARRIER, bio);
 
        wait_for_completion(&wait);
 
@@ -315,3 +315,73 @@ int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector)
        return ret;
 }
 EXPORT_SYMBOL(blkdev_issue_flush);
+
+static void blkdev_discard_end_io(struct bio *bio, int err)
+{
+       if (err) {
+               if (err == -EOPNOTSUPP)
+                       set_bit(BIO_EOPNOTSUPP, &bio->bi_flags);
+               clear_bit(BIO_UPTODATE, &bio->bi_flags);
+       }
+
+       bio_put(bio);
+}
+
+/**
+ * blkdev_issue_discard - queue a discard
+ * @bdev:      blockdev to issue discard for
+ * @sector:    start sector
+ * @nr_sects:  number of sectors to discard
+ * @gfp_mask:  memory allocation flags (for bio_alloc)
+ *
+ * Description:
+ *    Issue a discard request for the sectors in question. Does not wait.
+ */
+int blkdev_issue_discard(struct block_device *bdev,
+                        sector_t sector, sector_t nr_sects, gfp_t gfp_mask)
+{
+       struct request_queue *q;
+       struct bio *bio;
+       int ret = 0;
+
+       if (bdev->bd_disk == NULL)
+               return -ENXIO;
+
+       q = bdev_get_queue(bdev);
+       if (!q)
+               return -ENXIO;
+
+       if (!q->prepare_discard_fn)
+               return -EOPNOTSUPP;
+
+       while (nr_sects && !ret) {
+               bio = bio_alloc(gfp_mask, 0);
+               if (!bio)
+                       return -ENOMEM;
+
+               bio->bi_end_io = blkdev_discard_end_io;
+               bio->bi_bdev = bdev;
+
+               bio->bi_sector = sector;
+
+               if (nr_sects > q->max_hw_sectors) {
+                       bio->bi_size = q->max_hw_sectors << 9;
+                       nr_sects -= q->max_hw_sectors;
+                       sector += q->max_hw_sectors;
+               } else {
+                       bio->bi_size = nr_sects << 9;
+                       nr_sects = 0;
+               }
+               bio_get(bio);
+               submit_bio(DISCARD_BARRIER, bio);
+
+               /* Check if it failed immediately */
+               if (bio_flagged(bio, BIO_EOPNOTSUPP))
+                       ret = -EOPNOTSUPP;
+               else if (!bio_flagged(bio, BIO_UPTODATE))
+                       ret = -EIO;
+               bio_put(bio);
+       }
+       return ret;
+}
+EXPORT_SYMBOL(blkdev_issue_discard);
index 2cba5ef97b2b3a6d49559c8923a87e1ec128c2fa..2d053b584410255c39a2209aa90aee633083e7a0 100644 (file)
@@ -26,8 +26,6 @@
 #include <linux/swap.h>
 #include <linux/writeback.h>
 #include <linux/task_io_accounting_ops.h>
-#include <linux/interrupt.h>
-#include <linux/cpu.h>
 #include <linux/blktrace_api.h>
 #include <linux/fault-inject.h>
 
@@ -50,27 +48,26 @@ struct kmem_cache *blk_requestq_cachep;
  */
 static struct workqueue_struct *kblockd_workqueue;
 
-static DEFINE_PER_CPU(struct list_head, blk_cpu_done);
-
 static void drive_stat_acct(struct request *rq, int new_io)
 {
        struct hd_struct *part;
        int rw = rq_data_dir(rq);
+       int cpu;
 
        if (!blk_fs_request(rq) || !rq->rq_disk)
                return;
 
-       part = get_part(rq->rq_disk, rq->sector);
+       cpu = part_stat_lock();
+       part = disk_map_sector_rcu(rq->rq_disk, rq->sector);
+
        if (!new_io)
-               __all_stat_inc(rq->rq_disk, part, merges[rw], rq->sector);
+               part_stat_inc(cpu, part, merges[rw]);
        else {
-               disk_round_stats(rq->rq_disk);
-               rq->rq_disk->in_flight++;
-               if (part) {
-                       part_round_stats(part);
-                       part->in_flight++;
-               }
+               part_round_stats(cpu, part);
+               part_inc_in_flight(part);
        }
+
+       part_stat_unlock();
 }
 
 void blk_queue_congestion_threshold(struct request_queue *q)
@@ -113,7 +110,8 @@ void blk_rq_init(struct request_queue *q, struct request *rq)
        memset(rq, 0, sizeof(*rq));
 
        INIT_LIST_HEAD(&rq->queuelist);
-       INIT_LIST_HEAD(&rq->donelist);
+       INIT_LIST_HEAD(&rq->timeout_list);
+       rq->cpu = -1;
        rq->q = q;
        rq->sector = rq->hard_sector = (sector_t) -1;
        INIT_HLIST_NODE(&rq->hash);
@@ -308,7 +306,7 @@ void blk_unplug_timeout(unsigned long data)
        blk_add_trace_pdu_int(q, BLK_TA_UNPLUG_TIMER, NULL,
                                q->rq.count[READ] + q->rq.count[WRITE]);
 
-       kblockd_schedule_work(&q->unplug_work);
+       kblockd_schedule_work(q, &q->unplug_work);
 }
 
 void blk_unplug(struct request_queue *q)
@@ -325,6 +323,21 @@ void blk_unplug(struct request_queue *q)
 }
 EXPORT_SYMBOL(blk_unplug);
 
+static void blk_invoke_request_fn(struct request_queue *q)
+{
+       /*
+        * one level of recursion is ok and is much faster than kicking
+        * the unplug handling
+        */
+       if (!queue_flag_test_and_set(QUEUE_FLAG_REENTER, q)) {
+               q->request_fn(q);
+               queue_flag_clear(QUEUE_FLAG_REENTER, q);
+       } else {
+               queue_flag_set(QUEUE_FLAG_PLUGGED, q);
+               kblockd_schedule_work(q, &q->unplug_work);
+       }
+}
+
 /**
  * blk_start_queue - restart a previously stopped queue
  * @q:    The &struct request_queue in question
@@ -339,18 +352,7 @@ void blk_start_queue(struct request_queue *q)
        WARN_ON(!irqs_disabled());
 
        queue_flag_clear(QUEUE_FLAG_STOPPED, q);
-
-       /*
-        * one level of recursion is ok and is much faster than kicking
-        * the unplug handling
-        */
-       if (!queue_flag_test_and_set(QUEUE_FLAG_REENTER, q)) {
-               q->request_fn(q);
-               queue_flag_clear(QUEUE_FLAG_REENTER, q);
-       } else {
-               blk_plug_device(q);
-               kblockd_schedule_work(&q->unplug_work);
-       }
+       blk_invoke_request_fn(q);
 }
 EXPORT_SYMBOL(blk_start_queue);
 
@@ -408,15 +410,8 @@ void __blk_run_queue(struct request_queue *q)
         * Only recurse once to avoid overrunning the stack, let the unplug
         * handling reinvoke the handler shortly if we already got there.
         */
-       if (!elv_queue_empty(q)) {
-               if (!queue_flag_test_and_set(QUEUE_FLAG_REENTER, q)) {
-                       q->request_fn(q);
-                       queue_flag_clear(QUEUE_FLAG_REENTER, q);
-               } else {
-                       blk_plug_device(q);
-                       kblockd_schedule_work(&q->unplug_work);
-               }
-       }
+       if (!elv_queue_empty(q))
+               blk_invoke_request_fn(q);
 }
 EXPORT_SYMBOL(__blk_run_queue);
 
@@ -441,6 +436,14 @@ void blk_put_queue(struct request_queue *q)
 
 void blk_cleanup_queue(struct request_queue *q)
 {
+       /*
+        * We know we have process context here, so we can be a little
+        * cautious and ensure that pending block actions on this device
+        * are done before moving on. Going into this function, we should
+        * not have processes doing IO to this device.
+        */
+       blk_sync_queue(q);
+
        mutex_lock(&q->sysfs_lock);
        queue_flag_set_unlocked(QUEUE_FLAG_DEAD, q);
        mutex_unlock(&q->sysfs_lock);
@@ -496,6 +499,8 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
        }
 
        init_timer(&q->unplug_timer);
+       setup_timer(&q->timeout, blk_rq_timed_out_timer, (unsigned long) q);
+       INIT_LIST_HEAD(&q->timeout_list);
 
        kobject_init(&q->kobj, &blk_queue_ktype);
 
@@ -531,7 +536,7 @@ EXPORT_SYMBOL(blk_alloc_queue_node);
  *    request queue; this lock will be taken also from interrupt context, so irq
  *    disabling is needed for it.
  *
- *    Function returns a pointer to the initialized request queue, or NULL if
+ *    Function returns a pointer to the initialized request queue, or %NULL if
  *    it didn't succeed.
  *
  * Note:
@@ -569,7 +574,8 @@ blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id)
        q->request_fn           = rfn;
        q->prep_rq_fn           = NULL;
        q->unplug_fn            = generic_unplug_device;
-       q->queue_flags          = (1 << QUEUE_FLAG_CLUSTER);
+       q->queue_flags          = (1 << QUEUE_FLAG_CLUSTER |
+                                  1 << QUEUE_FLAG_STACKABLE);
        q->queue_lock           = lock;
 
        blk_queue_segment_boundary(q, 0xffffffff);
@@ -624,10 +630,6 @@ blk_alloc_request(struct request_queue *q, int rw, int priv, gfp_t gfp_mask)
 
        blk_rq_init(q, rq);
 
-       /*
-        * first three bits are identical in rq->cmd_flags and bio->bi_rw,
-        * see bio.h and blkdev.h
-        */
        rq->cmd_flags = rw | REQ_ALLOCED;
 
        if (priv) {
@@ -888,9 +890,11 @@ EXPORT_SYMBOL(blk_get_request);
  */
 void blk_start_queueing(struct request_queue *q)
 {
-       if (!blk_queue_plugged(q))
+       if (!blk_queue_plugged(q)) {
+               if (unlikely(blk_queue_stopped(q)))
+                       return;
                q->request_fn(q);
-       else
+       else
                __generic_unplug_device(q);
 }
 EXPORT_SYMBOL(blk_start_queueing);
@@ -907,6 +911,8 @@ EXPORT_SYMBOL(blk_start_queueing);
  */
 void blk_requeue_request(struct request_queue *q, struct request *rq)
 {
+       blk_delete_timer(rq);
+       blk_clear_rq_complete(rq);
        blk_add_trace_rq(q, rq, BLK_TA_REQUEUE);
 
        if (blk_rq_tagged(rq))
@@ -917,7 +923,7 @@ void blk_requeue_request(struct request_queue *q, struct request *rq)
 EXPORT_SYMBOL(blk_requeue_request);
 
 /**
- * blk_insert_request - insert a special request in to a request queue
+ * blk_insert_request - insert a special request into a request queue
  * @q:         request queue where request should be inserted
  * @rq:                request to be inserted
  * @at_head:   insert request at head or tail of queue
@@ -927,8 +933,8 @@ EXPORT_SYMBOL(blk_requeue_request);
  *    Many block devices need to execute commands asynchronously, so they don't
  *    block the whole kernel from preemption during request execution.  This is
  *    accomplished normally by inserting aritficial requests tagged as
- *    REQ_SPECIAL in to the corresponding request queue, and letting them be
- *    scheduled for actual execution by the request queue.
+ *    REQ_TYPE_SPECIAL in to the corresponding request queue, and letting them
+ *    be scheduled for actual execution by the request queue.
  *
  *    We have the option of inserting the head or the tail of the queue.
  *    Typically we use the tail for new ioctls and so forth.  We use the head
@@ -982,8 +988,22 @@ static inline void add_request(struct request_queue *q, struct request *req)
        __elv_add_request(q, req, ELEVATOR_INSERT_SORT, 0);
 }
 
-/*
- * disk_round_stats()  - Round off the performance stats on a struct
+static void part_round_stats_single(int cpu, struct hd_struct *part,
+                                   unsigned long now)
+{
+       if (now == part->stamp)
+               return;
+
+       if (part->in_flight) {
+               __part_stat_add(cpu, part, time_in_queue,
+                               part->in_flight * (now - part->stamp));
+               __part_stat_add(cpu, part, io_ticks, (now - part->stamp));
+       }
+       part->stamp = now;
+}
+
+/**
+ * part_round_stats()  - Round off the performance stats on a struct
  * disk_stats.
  *
  * The average IO queue length and utilisation statistics are maintained
@@ -997,36 +1017,15 @@ static inline void add_request(struct request_queue *q, struct request *req)
  * /proc/diskstats.  This accounts immediately for all queue usage up to
  * the current jiffies and restarts the counters again.
  */
-void disk_round_stats(struct gendisk *disk)
+void part_round_stats(int cpu, struct hd_struct *part)
 {
        unsigned long now = jiffies;
 
-       if (now == disk->stamp)
-               return;
-
-       if (disk->in_flight) {
-               __disk_stat_add(disk, time_in_queue,
-                               disk->in_flight * (now - disk->stamp));
-               __disk_stat_add(disk, io_ticks, (now - disk->stamp));
-       }
-       disk->stamp = now;
-}
-EXPORT_SYMBOL_GPL(disk_round_stats);
-
-void part_round_stats(struct hd_struct *part)
-{
-       unsigned long now = jiffies;
-
-       if (now == part->stamp)
-               return;
-
-       if (part->in_flight) {
-               __part_stat_add(part, time_in_queue,
-                               part->in_flight * (now - part->stamp));
-               __part_stat_add(part, io_ticks, (now - part->stamp));
-       }
-       part->stamp = now;
+       if (part->partno)
+               part_round_stats_single(cpu, &part_to_disk(part)->part0, now);
+       part_round_stats_single(cpu, part, now);
 }
+EXPORT_SYMBOL_GPL(part_round_stats);
 
 /*
  * queue lock must be held
@@ -1070,6 +1069,7 @@ EXPORT_SYMBOL(blk_put_request);
 
 void init_request_from_bio(struct request *req, struct bio *bio)
 {
+       req->cpu = bio->bi_comp_cpu;
        req->cmd_type = REQ_TYPE_FS;
 
        /*
@@ -1081,7 +1081,12 @@ void init_request_from_bio(struct request *req, struct bio *bio)
        /*
         * REQ_BARRIER implies no merging, but lets make it explicit
         */
-       if (unlikely(bio_barrier(bio)))
+       if (unlikely(bio_discard(bio))) {
+               req->cmd_flags |= REQ_DISCARD;
+               if (bio_barrier(bio))
+                       req->cmd_flags |= REQ_SOFTBARRIER;
+               req->q->prepare_discard_fn(req->q, req);
+       } else if (unlikely(bio_barrier(bio)))
                req->cmd_flags |= (REQ_HARDBARRIER | REQ_NOMERGE);
 
        if (bio_sync(bio))
@@ -1099,7 +1104,7 @@ void init_request_from_bio(struct request *req, struct bio *bio)
 static int __make_request(struct request_queue *q, struct bio *bio)
 {
        struct request *req;
-       int el_ret, nr_sectors, barrier, err;
+       int el_ret, nr_sectors, barrier, discard, err;
        const unsigned short prio = bio_prio(bio);
        const int sync = bio_sync(bio);
        int rw_flags;
@@ -1114,7 +1119,14 @@ static int __make_request(struct request_queue *q, struct bio *bio)
        blk_queue_bounce(q, &bio);
 
        barrier = bio_barrier(bio);
-       if (unlikely(barrier) && (q->next_ordered == QUEUE_ORDERED_NONE)) {
+       if (unlikely(barrier) && bio_has_data(bio) &&
+           (q->next_ordered == QUEUE_ORDERED_NONE)) {
+               err = -EOPNOTSUPP;
+               goto end_io;
+       }
+
+       discard = bio_discard(bio);
+       if (unlikely(discard) && !q->prepare_discard_fn) {
                err = -EOPNOTSUPP;
                goto end_io;
        }
@@ -1138,6 +1150,8 @@ static int __make_request(struct request_queue *q, struct bio *bio)
                req->biotail = bio;
                req->nr_sectors = req->hard_nr_sectors += nr_sectors;
                req->ioprio = ioprio_best(req->ioprio, prio);
+               if (!blk_rq_cpu_valid(req))
+                       req->cpu = bio->bi_comp_cpu;
                drive_stat_acct(req, 0);
                if (!attempt_back_merge(q, req))
                        elv_merged_request(q, req, el_ret);
@@ -1165,6 +1179,8 @@ static int __make_request(struct request_queue *q, struct bio *bio)
                req->sector = req->hard_sector = bio->bi_sector;
                req->nr_sectors = req->hard_nr_sectors += nr_sectors;
                req->ioprio = ioprio_best(req->ioprio, prio);
+               if (!blk_rq_cpu_valid(req))
+                       req->cpu = bio->bi_comp_cpu;
                drive_stat_acct(req, 0);
                if (!attempt_front_merge(q, req))
                        elv_merged_request(q, req, el_ret);
@@ -1200,13 +1216,15 @@ get_rq:
        init_request_from_bio(req, bio);
 
        spin_lock_irq(q->queue_lock);
+       if (test_bit(QUEUE_FLAG_SAME_COMP, &q->queue_flags) ||
+           bio_flagged(bio, BIO_CPU_AFFINE))
+               req->cpu = blk_cpu_to_group(smp_processor_id());
        if (elv_queue_empty(q))
                blk_plug_device(q);
        add_request(q, req);
 out:
        if (sync)
                __generic_unplug_device(q);
-
        spin_unlock_irq(q->queue_lock);
        return 0;
 
@@ -1260,8 +1278,9 @@ __setup("fail_make_request=", setup_fail_make_request);
 
 static int should_fail_request(struct bio *bio)
 {
-       if ((bio->bi_bdev->bd_disk->flags & GENHD_FL_FAIL) ||
-           (bio->bi_bdev->bd_part && bio->bi_bdev->bd_part->make_it_fail))
+       struct hd_struct *part = bio->bi_bdev->bd_part;
+
+       if (part_to_disk(part)->part0.make_it_fail || part->make_it_fail)
                return should_fail(&fail_make_request, bio->bi_size);
 
        return 0;
@@ -1314,7 +1333,7 @@ static inline int bio_check_eod(struct bio *bio, unsigned int nr_sectors)
 }
 
 /**
- * generic_make_request: hand a buffer to its device driver for I/O
+ * generic_make_request - hand a buffer to its device driver for I/O
  * @bio:  The bio describing the location in memory and on the device.
  *
  * generic_make_request() is used to make I/O requests of block
@@ -1409,7 +1428,8 @@ end_io:
 
                if (bio_check_eod(bio, nr_sectors))
                        goto end_io;
-               if (bio_empty_barrier(bio) && !q->prepare_flush_fn) {
+               if ((bio_empty_barrier(bio) && !q->prepare_flush_fn) ||
+                   (bio_discard(bio) && !q->prepare_discard_fn)) {
                        err = -EOPNOTSUPP;
                        goto end_io;
                }
@@ -1471,13 +1491,13 @@ void generic_make_request(struct bio *bio)
 EXPORT_SYMBOL(generic_make_request);
 
 /**
- * submit_bio: submit a bio to the block device layer for I/O
+ * submit_bio - submit a bio to the block device layer for I/O
  * @rw: whether to %READ or %WRITE, or maybe to %READA (read ahead)
  * @bio: The &struct bio which describes the I/O
  *
  * submit_bio() is very similar in purpose to generic_make_request(), and
  * uses that function to do most of the work. Both are fairly rough
- * interfaces, @bio must be presetup and ready for I/O.
+ * interfaces; @bio must be presetup and ready for I/O.
  *
  */
 void submit_bio(int rw, struct bio *bio)
@@ -1490,11 +1510,7 @@ void submit_bio(int rw, struct bio *bio)
         * If it's a regular read/write or a barrier with data attached,
         * go through the normal accounting stuff before submission.
         */
-       if (!bio_empty_barrier(bio)) {
-
-               BIO_BUG_ON(!bio->bi_size);
-               BIO_BUG_ON(!bio->bi_io_vec);
-
+       if (bio_has_data(bio)) {
                if (rw & WRITE) {
                        count_vm_events(PGPGOUT, count);
                } else {
@@ -1516,10 +1532,91 @@ void submit_bio(int rw, struct bio *bio)
 }
 EXPORT_SYMBOL(submit_bio);
 
+/**
+ * blk_rq_check_limits - Helper function to check a request for the queue limit
+ * @q:  the queue
+ * @rq: the request being checked
+ *
+ * Description:
+ *    @rq may have been made based on weaker limitations of upper-level queues
+ *    in request stacking drivers, and it may violate the limitation of @q.
+ *    Since the block layer and the underlying device driver trust @rq
+ *    after it is inserted to @q, it should be checked against @q before
+ *    the insertion using this generic function.
+ *
+ *    This function should also be useful for request stacking drivers
+ *    in some cases below, so export this fuction.
+ *    Request stacking drivers like request-based dm may change the queue
+ *    limits while requests are in the queue (e.g. dm's table swapping).
+ *    Such request stacking drivers should check those requests agaist
+ *    the new queue limits again when they dispatch those requests,
+ *    although such checkings are also done against the old queue limits
+ *    when submitting requests.
+ */
+int blk_rq_check_limits(struct request_queue *q, struct request *rq)
+{
+       if (rq->nr_sectors > q->max_sectors ||
+           rq->data_len > q->max_hw_sectors << 9) {
+               printk(KERN_ERR "%s: over max size limit.\n", __func__);
+               return -EIO;
+       }
+
+       /*
+        * queue's settings related to segment counting like q->bounce_pfn
+        * may differ from that of other stacking queues.
+        * Recalculate it to check the request correctly on this queue's
+        * limitation.
+        */
+       blk_recalc_rq_segments(rq);
+       if (rq->nr_phys_segments > q->max_phys_segments ||
+           rq->nr_phys_segments > q->max_hw_segments) {
+               printk(KERN_ERR "%s: over max segments limit.\n", __func__);
+               return -EIO;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(blk_rq_check_limits);
+
+/**
+ * blk_insert_cloned_request - Helper for stacking drivers to submit a request
+ * @q:  the queue to submit the request
+ * @rq: the request being queued
+ */
+int blk_insert_cloned_request(struct request_queue *q, struct request *rq)
+{
+       unsigned long flags;
+
+       if (blk_rq_check_limits(q, rq))
+               return -EIO;
+
+#ifdef CONFIG_FAIL_MAKE_REQUEST
+       if (rq->rq_disk && rq->rq_disk->part0.make_it_fail &&
+           should_fail(&fail_make_request, blk_rq_bytes(rq)))
+               return -EIO;
+#endif
+
+       spin_lock_irqsave(q->queue_lock, flags);
+
+       /*
+        * Submitting request must be dequeued before calling this function
+        * because it will be linked to another request_queue
+        */
+       BUG_ON(blk_queued_rq(rq));
+
+       drive_stat_acct(rq, 1);
+       __elv_add_request(q, rq, ELEVATOR_INSERT_BACK, 0);
+
+       spin_unlock_irqrestore(q->queue_lock, flags);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(blk_insert_cloned_request);
+
 /**
  * __end_that_request_first - end I/O on a request
  * @req:      the request being processed
- * @error:    0 for success, < 0 for error
+ * @error:    %0 for success, < %0 for error
  * @nr_bytes: number of bytes to complete
  *
  * Description:
@@ -1527,8 +1624,8 @@ EXPORT_SYMBOL(submit_bio);
  *     for the next range of segments (if any) in the cluster.
  *
  * Return:
- *     0 - we are done with this request, call end_that_request_last()
- *     1 - still buffers pending for this request
+ *     %0 - we are done with this request, call end_that_request_last()
+ *     %1 - still buffers pending for this request
  **/
 static int __end_that_request_first(struct request *req, int error,
                                    int nr_bytes)
@@ -1539,7 +1636,7 @@ static int __end_that_request_first(struct request *req, int error,
        blk_add_trace_rq(req->q, req, BLK_TA_COMPLETE);
 
        /*
-        * for a REQ_BLOCK_PC request, we want to carry any eventual
+        * for a REQ_TYPE_BLOCK_PC request, we want to carry any eventual
         * sense key with us all the way through
         */
        if (!blk_pc_request(req))
@@ -1552,11 +1649,14 @@ static int __end_that_request_first(struct request *req, int error,
        }
 
        if (blk_fs_request(req) && req->rq_disk) {
-               struct hd_struct *part = get_part(req->rq_disk, req->sector);
                const int rw = rq_data_dir(req);
+               struct hd_struct *part;
+               int cpu;
 
-               all_stat_add(req->rq_disk, part, sectors[rw],
-                               nr_bytes >> 9, req->sector);
+               cpu = part_stat_lock();
+               part = disk_map_sector_rcu(req->rq_disk, req->sector);
+               part_stat_add(cpu, part, sectors[rw], nr_bytes >> 9);
+               part_stat_unlock();
        }
 
        total_bytes = bio_nbytes = 0;
@@ -1640,82 +1740,6 @@ static int __end_that_request_first(struct request *req, int error,
        return 1;
 }
 
-/*
- * splice the completion data to a local structure and hand off to
- * process_completion_queue() to complete the requests
- */
-static void blk_done_softirq(struct softirq_action *h)
-{
-       struct list_head *cpu_list, local_list;
-
-       local_irq_disable();
-       cpu_list = &__get_cpu_var(blk_cpu_done);
-       list_replace_init(cpu_list, &local_list);
-       local_irq_enable();
-
-       while (!list_empty(&local_list)) {
-               struct request *rq;
-
-               rq = list_entry(local_list.next, struct request, donelist);
-               list_del_init(&rq->donelist);
-               rq->q->softirq_done_fn(rq);
-       }
-}
-
-static int __cpuinit blk_cpu_notify(struct notifier_block *self,
-                                   unsigned long action, void *hcpu)
-{
-       /*
-        * If a CPU goes away, splice its entries to the current CPU
-        * and trigger a run of the softirq
-        */
-       if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) {
-               int cpu = (unsigned long) hcpu;
-
-               local_irq_disable();
-               list_splice_init(&per_cpu(blk_cpu_done, cpu),
-                                &__get_cpu_var(blk_cpu_done));
-               raise_softirq_irqoff(BLOCK_SOFTIRQ);
-               local_irq_enable();
-       }
-
-       return NOTIFY_OK;
-}
-
-
-static struct notifier_block blk_cpu_notifier __cpuinitdata = {
-       .notifier_call  = blk_cpu_notify,
-};
-
-/**
- * blk_complete_request - end I/O on a request
- * @req:      the request being processed
- *
- * Description:
- *     Ends all I/O on a request. It does not handle partial completions,
- *     unless the driver actually implements this in its completion callback
- *     through requeueing. The actual completion happens out-of-order,
- *     through a softirq handler. The user must have registered a completion
- *     callback through blk_queue_softirq_done().
- **/
-
-void blk_complete_request(struct request *req)
-{
-       struct list_head *cpu_list;
-       unsigned long flags;
-
-       BUG_ON(!req->q->softirq_done_fn);
-
-       local_irq_save(flags);
-
-       cpu_list = &__get_cpu_var(blk_cpu_done);
-       list_add_tail(&req->donelist, cpu_list);
-       raise_softirq_irqoff(BLOCK_SOFTIRQ);
-
-       local_irq_restore(flags);
-}
-EXPORT_SYMBOL(blk_complete_request);
-
 /*
  * queue lock must be held
  */
@@ -1723,6 +1747,8 @@ static void end_that_request_last(struct request *req, int error)
 {
        struct gendisk *disk = req->rq_disk;
 
+       blk_delete_timer(req);
+
        if (blk_rq_tagged(req))
                blk_queue_end_tag(req->q, req);
 
@@ -1740,16 +1766,18 @@ static void end_that_request_last(struct request *req, int error)
        if (disk && blk_fs_request(req) && req != &req->q->bar_rq) {
                unsigned long duration = jiffies - req->start_time;
                const int rw = rq_data_dir(req);
-               struct hd_struct *part = get_part(disk, req->sector);
-
-               __all_stat_inc(disk, part, ios[rw], req->sector);
-               __all_stat_add(disk, part, ticks[rw], duration, req->sector);
-               disk_round_stats(disk);
-               disk->in_flight--;
-               if (part) {
-                       part_round_stats(part);
-                       part->in_flight--;
-               }
+               struct hd_struct *part;
+               int cpu;
+
+               cpu = part_stat_lock();
+               part = disk_map_sector_rcu(disk, req->sector);
+
+               part_stat_inc(cpu, part, ios[rw]);
+               part_stat_add(cpu, part, ticks[rw], duration);
+               part_round_stats(cpu, part);
+               part_dec_in_flight(part);
+
+               part_stat_unlock();
        }
 
        if (req->end_io)
@@ -1762,17 +1790,6 @@ static void end_that_request_last(struct request *req, int error)
        }
 }
 
-static inline void __end_request(struct request *rq, int uptodate,
-                                unsigned int nr_bytes)
-{
-       int error = 0;
-
-       if (uptodate <= 0)
-               error = uptodate ? uptodate : -EIO;
-
-       __blk_end_request(rq, error, nr_bytes);
-}
-
 /**
  * blk_rq_bytes - Returns bytes left to complete in the entire request
  * @rq: the request being processed
@@ -1802,75 +1819,58 @@ unsigned int blk_rq_cur_bytes(struct request *rq)
 }
 EXPORT_SYMBOL_GPL(blk_rq_cur_bytes);
 
-/**
- * end_queued_request - end all I/O on a queued request
- * @rq:                the request being processed
- * @uptodate:  error value or 0/1 uptodate flag
- *
- * Description:
- *     Ends all I/O on a request, and removes it from the block layer queues.
- *     Not suitable for normal IO completion, unless the driver still has
- *     the request attached to the block layer.
- *
- **/
-void end_queued_request(struct request *rq, int uptodate)
-{
-       __end_request(rq, uptodate, blk_rq_bytes(rq));
-}
-EXPORT_SYMBOL(end_queued_request);
-
-/**
- * end_dequeued_request - end all I/O on a dequeued request
- * @rq:                the request being processed
- * @uptodate:  error value or 0/1 uptodate flag
- *
- * Description:
- *     Ends all I/O on a request. The request must already have been
- *     dequeued using blkdev_dequeue_request(), as is normally the case
- *     for most drivers.
- *
- **/
-void end_dequeued_request(struct request *rq, int uptodate)
-{
-       __end_request(rq, uptodate, blk_rq_bytes(rq));
-}
-EXPORT_SYMBOL(end_dequeued_request);
-
-
 /**
  * end_request - end I/O on the current segment of the request
  * @req:       the request being processed
- * @uptodate:  error value or 0/1 uptodate flag
+ * @uptodate:  error value or %0/%1 uptodate flag
  *
  * Description:
  *     Ends I/O on the current segment of a request. If that is the only
  *     remaining segment, the request is also completed and freed.
  *
- *     This is a remnant of how older block drivers handled IO completions.
- *     Modern drivers typically end IO on the full request in one go, unless
+ *     This is a remnant of how older block drivers handled I/O completions.
+ *     Modern drivers typically end I/O on the full request in one go, unless
  *     they have a residual value to account for. For that case this function
  *     isn't really useful, unless the residual just happens to be the
  *     full current segment. In other words, don't use this function in new
- *     code. Either use end_request_completely(), or the
- *     end_that_request_chunk() (along with end_that_request_last()) for
- *     partial completions.
- *
+ *     code. Use blk_end_request() or __blk_end_request() to end a request.
  **/
 void end_request(struct request *req, int uptodate)
 {
-       __end_request(req, uptodate, req->hard_cur_sectors << 9);
+       int error = 0;
+
+       if (uptodate <= 0)
+               error = uptodate ? uptodate : -EIO;
+
+       __blk_end_request(req, error, req->hard_cur_sectors << 9);
 }
 EXPORT_SYMBOL(end_request);
 
+static int end_that_request_data(struct request *rq, int error,
+                                unsigned int nr_bytes, unsigned int bidi_bytes)
+{
+       if (rq->bio) {
+               if (__end_that_request_first(rq, error, nr_bytes))
+                       return 1;
+
+               /* Bidi request must be completed as a whole */
+               if (blk_bidi_rq(rq) &&
+                   __end_that_request_first(rq->next_rq, error, bidi_bytes))
+                       return 1;
+       }
+
+       return 0;
+}
+
 /**
  * blk_end_io - Generic end_io function to complete a request.
  * @rq:           the request being processed
- * @error:        0 for success, < 0 for error
+ * @error:        %0 for success, < %0 for error
  * @nr_bytes:     number of bytes to complete @rq
  * @bidi_bytes:   number of bytes to complete @rq->next_rq
  * @drv_callback: function called between completion of bios in the request
  *                and completion of the request.
- *                If the callback returns non 0, this helper returns without
+ *                If the callback returns non %0, this helper returns without
  *                completion of the request.
  *
  * Description:
@@ -1878,8 +1878,8 @@ EXPORT_SYMBOL(end_request);
  *     If @rq has leftover, sets it up for the next range of segments.
  *
  * Return:
- *     0 - we are done with this request
- *     1 - this request is not freed yet, it still has pending buffers.
+ *     %0 - we are done with this request
+ *     %1 - this request is not freed yet, it still has pending buffers.
  **/
 static int blk_end_io(struct request *rq, int error, unsigned int nr_bytes,
                      unsigned int bidi_bytes,
@@ -1888,15 +1888,8 @@ static int blk_end_io(struct request *rq, int error, unsigned int nr_bytes,
        struct request_queue *q = rq->q;
        unsigned long flags = 0UL;
 
-       if (blk_fs_request(rq) || blk_pc_request(rq)) {
-               if (__end_that_request_first(rq, error, nr_bytes))
-                       return 1;
-
-               /* Bidi request must be completed as a whole */
-               if (blk_bidi_rq(rq) &&
-                   __end_that_request_first(rq->next_rq, error, bidi_bytes))
-                       return 1;
-       }
+       if (end_that_request_data(rq, error, nr_bytes, bidi_bytes))
+               return 1;
 
        /* Special feature for tricky drivers */
        if (drv_callback && drv_callback(rq))
@@ -1914,7 +1907,7 @@ static int blk_end_io(struct request *rq, int error, unsigned int nr_bytes,
 /**
  * blk_end_request - Helper function for drivers to complete the request.
  * @rq:       the request being processed
- * @error:    0 for success, < 0 for error
+ * @error:    %0 for success, < %0 for error
  * @nr_bytes: number of bytes to complete
  *
  * Description:
@@ -1922,8 +1915,8 @@ static int blk_end_io(struct request *rq, int error, unsigned int nr_bytes,
  *     If @rq has leftover, sets it up for the next range of segments.
  *
  * Return:
- *     0 - we are done with this request
- *     1 - still buffers pending for this request
+ *     %0 - we are done with this request
+ *     %1 - still buffers pending for this request
  **/
 int blk_end_request(struct request *rq, int error, unsigned int nr_bytes)
 {
@@ -1934,22 +1927,20 @@ EXPORT_SYMBOL_GPL(blk_end_request);
 /**
  * __blk_end_request - Helper function for drivers to complete the request.
  * @rq:       the request being processed
- * @error:    0 for success, < 0 for error
+ * @error:    %0 for success, < %0 for error
  * @nr_bytes: number of bytes to complete
  *
  * Description:
  *     Must be called with queue lock held unlike blk_end_request().
  *
  * Return:
- *     0 - we are done with this request
- *     1 - still buffers pending for this request
+ *     %0 - we are done with this request
+ *     %1 - still buffers pending for this request
  **/
 int __blk_end_request(struct request *rq, int error, unsigned int nr_bytes)
 {
-       if (blk_fs_request(rq) || blk_pc_request(rq)) {
-               if (__end_that_request_first(rq, error, nr_bytes))
-                       return 1;
-       }
+       if (rq->bio && __end_that_request_first(rq, error, nr_bytes))
+               return 1;
 
        add_disk_randomness(rq->rq_disk);
 
@@ -1962,7 +1953,7 @@ EXPORT_SYMBOL_GPL(__blk_end_request);
 /**
  * blk_end_bidi_request - Helper function for drivers to complete bidi request.
  * @rq:         the bidi request being processed
- * @error:      0 for success, < 0 for error
+ * @error:      %0 for success, < %0 for error
  * @nr_bytes:   number of bytes to complete @rq
  * @bidi_bytes: number of bytes to complete @rq->next_rq
  *
@@ -1970,8 +1961,8 @@ EXPORT_SYMBOL_GPL(__blk_end_request);
  *     Ends I/O on a number of bytes attached to @rq and @rq->next_rq.
  *
  * Return:
- *     0 - we are done with this request
- *     1 - still buffers pending for this request
+ *     %0 - we are done with this request
+ *     %1 - still buffers pending for this request
  **/
 int blk_end_bidi_request(struct request *rq, int error, unsigned int nr_bytes,
                         unsigned int bidi_bytes)
@@ -1980,14 +1971,44 @@ int blk_end_bidi_request(struct request *rq, int error, unsigned int nr_bytes,
 }
 EXPORT_SYMBOL_GPL(blk_end_bidi_request);
 
+/**
+ * blk_update_request - Special helper function for request stacking drivers
+ * @rq:           the request being processed
+ * @error:        %0 for success, < %0 for error
+ * @nr_bytes:     number of bytes to complete @rq
+ *
+ * Description:
+ *     Ends I/O on a number of bytes attached to @rq, but doesn't complete
+ *     the request structure even if @rq doesn't have leftover.
+ *     If @rq has leftover, sets it up for the next range of segments.
+ *
+ *     This special helper function is only for request stacking drivers
+ *     (e.g. request-based dm) so that they can handle partial completion.
+ *     Actual device drivers should use blk_end_request instead.
+ */
+void blk_update_request(struct request *rq, int error, unsigned int nr_bytes)
+{
+       if (!end_that_request_data(rq, error, nr_bytes, 0)) {
+               /*
+                * These members are not updated in end_that_request_data()
+                * when all bios are completed.
+                * Update them so that the request stacking driver can find
+                * how many bytes remain in the request later.
+                */
+               rq->nr_sectors = rq->hard_nr_sectors = 0;
+               rq->current_nr_sectors = rq->hard_cur_sectors = 0;
+       }
+}
+EXPORT_SYMBOL_GPL(blk_update_request);
+
 /**
  * blk_end_request_callback - Special helper function for tricky drivers
  * @rq:           the request being processed
- * @error:        0 for success, < 0 for error
+ * @error:        %0 for success, < %0 for error
  * @nr_bytes:     number of bytes to complete
  * @drv_callback: function called between completion of bios in the request
  *                and completion of the request.
- *                If the callback returns non 0, this helper returns without
+ *                If the callback returns non %0, this helper returns without
  *                completion of the request.
  *
  * Description:
@@ -2000,10 +2021,10 @@ EXPORT_SYMBOL_GPL(blk_end_bidi_request);
  *     Don't use this interface in other places anymore.
  *
  * Return:
- *     0 - we are done with this request
- *     1 - this request is not freed yet.
- *         this request still has pending buffers or
- *         the driver doesn't want to finish this request yet.
+ *     %0 - we are done with this request
+ *     %1 - this request is not freed yet.
+ *          this request still has pending buffers or
+ *          the driver doesn't want to finish this request yet.
  **/
 int blk_end_request_callback(struct request *rq, int error,
                             unsigned int nr_bytes,
@@ -2016,15 +2037,17 @@ EXPORT_SYMBOL_GPL(blk_end_request_callback);
 void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
                     struct bio *bio)
 {
-       /* first two bits are identical in rq->cmd_flags and bio->bi_rw */
+       /* Bit 0 (R/W) is identical in rq->cmd_flags and bio->bi_rw, and
+          we want BIO_RW_AHEAD (bit 1) to imply REQ_FAILFAST (bit 1). */
        rq->cmd_flags |= (bio->bi_rw & 3);
 
-       rq->nr_phys_segments = bio_phys_segments(q, bio);
-       rq->nr_hw_segments = bio_hw_segments(q, bio);
+       if (bio_has_data(bio)) {
+               rq->nr_phys_segments = bio_phys_segments(q, bio);
+               rq->buffer = bio_data(bio);
+       }
        rq->current_nr_sectors = bio_cur_sectors(bio);
        rq->hard_cur_sectors = rq->current_nr_sectors;
        rq->hard_nr_sectors = rq->nr_sectors = bio_sectors(bio);
-       rq->buffer = bio_data(bio);
        rq->data_len = bio->bi_size;
 
        rq->bio = rq->biotail = bio;
@@ -2033,7 +2056,35 @@ void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
                rq->rq_disk = bio->bi_bdev->bd_disk;
 }
 
-int kblockd_schedule_work(struct work_struct *work)
+/**
+ * blk_lld_busy - Check if underlying low-level drivers of a device are busy
+ * @q : the queue of the device being checked
+ *
+ * Description:
+ *    Check if underlying low-level drivers of a device are busy.
+ *    If the drivers want to export their busy state, they must set own
+ *    exporting function using blk_queue_lld_busy() first.
+ *
+ *    Basically, this function is used only by request stacking drivers
+ *    to stop dispatching requests to underlying devices when underlying
+ *    devices are busy.  This behavior helps more I/O merging on the queue
+ *    of the request stacking driver and prevents I/O throughput regression
+ *    on burst I/O load.
+ *
+ * Return:
+ *    0 - Not busy (The request stacking driver should dispatch request)
+ *    1 - Busy (The request stacking driver should stop dispatching request)
+ */
+int blk_lld_busy(struct request_queue *q)
+{
+       if (q->lld_busy_fn)
+               return q->lld_busy_fn(q);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(blk_lld_busy);
+
+int kblockd_schedule_work(struct request_queue *q, struct work_struct *work)
 {
        return queue_work(kblockd_workqueue, work);
 }
@@ -2047,8 +2098,6 @@ EXPORT_SYMBOL(kblockd_flush_work);
 
 int __init blk_dev_init(void)
 {
-       int i;
-
        kblockd_workqueue = create_workqueue("kblockd");
        if (!kblockd_workqueue)
                panic("Failed to create kblockd\n");
@@ -2059,12 +2108,6 @@ int __init blk_dev_init(void)
        blk_requestq_cachep = kmem_cache_create("blkdev_queue",
                        sizeof(struct request_queue), 0, SLAB_PANIC, NULL);
 
-       for_each_possible_cpu(i)
-               INIT_LIST_HEAD(&per_cpu(blk_cpu_done, i));
-
-       open_softirq(BLOCK_SOFTIRQ, blk_done_softirq);
-       register_hotcpu_notifier(&blk_cpu_notifier);
-
        return 0;
 }
 
index 9bceff7674f220acaa9b9580181a1466a8024388..6af716d1e54e038468c455e093f2d1e08719812e 100644 (file)
@@ -16,7 +16,7 @@
 /**
  * blk_end_sync_rq - executes a completion event on a request
  * @rq: request to complete
- * @error: end io status of the request
+ * @error: end I/O status of the request
  */
 static void blk_end_sync_rq(struct request *rq, int error)
 {
@@ -41,7 +41,7 @@ static void blk_end_sync_rq(struct request *rq, int error)
  * @done:      I/O completion handler
  *
  * Description:
- *    Insert a fully prepared request at the back of the io scheduler queue
+ *    Insert a fully prepared request at the back of the I/O scheduler queue
  *    for execution.  Don't wait for completion.
  */
 void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,
@@ -72,7 +72,7 @@ EXPORT_SYMBOL_GPL(blk_execute_rq_nowait);
  * @at_head:    insert request at head or tail of queue
  *
  * Description:
- *    Insert a fully prepared request at the back of the io scheduler queue
+ *    Insert a fully prepared request at the back of the I/O scheduler queue
  *    for execution and wait for completion.
  */
 int blk_execute_rq(struct request_queue *q, struct gendisk *bd_disk,
index 3f1a8478cc384b041c8ef8c66f633eb85e10b36d..61a8e2f8fdd0bbb384fe7eab86860df6f03f4949 100644 (file)
@@ -108,51 +108,51 @@ new_segment:
 EXPORT_SYMBOL(blk_rq_map_integrity_sg);
 
 /**
- * blk_integrity_compare - Compare integrity profile of two block devices
- * @b1:                Device to compare
- * @b2:                Device to compare
+ * blk_integrity_compare - Compare integrity profile of two disks
+ * @gd1:       Disk to compare
+ * @gd2:       Disk to compare
  *
  * Description: Meta-devices like DM and MD need to verify that all
  * sub-devices use the same integrity format before advertising to
  * upper layers that they can send/receive integrity metadata.  This
- * function can be used to check whether two block devices have
+ * function can be used to check whether two gendisk devices have
  * compatible integrity formats.
  */
-int blk_integrity_compare(struct block_device *bd1, struct block_device *bd2)
+int blk_integrity_compare(struct gendisk *gd1, struct gendisk *gd2)
 {
-       struct blk_integrity *b1 = bd1->bd_disk->integrity;
-       struct blk_integrity *b2 = bd2->bd_disk->integrity;
+       struct blk_integrity *b1 = gd1->integrity;
+       struct blk_integrity *b2 = gd2->integrity;
 
-       BUG_ON(bd1->bd_disk == NULL);
-       BUG_ON(bd2->bd_disk == NULL);
+       if (!b1 && !b2)
+               return 0;
 
        if (!b1 || !b2)
-               return 0;
+               return -1;
 
        if (b1->sector_size != b2->sector_size) {
                printk(KERN_ERR "%s: %s/%s sector sz %u != %u\n", __func__,
-                      bd1->bd_disk->disk_name, bd2->bd_disk->disk_name,
+                      gd1->disk_name, gd2->disk_name,
                       b1->sector_size, b2->sector_size);
                return -1;
        }
 
        if (b1->tuple_size != b2->tuple_size) {
                printk(KERN_ERR "%s: %s/%s tuple sz %u != %u\n", __func__,
-                      bd1->bd_disk->disk_name, bd2->bd_disk->disk_name,
+                      gd1->disk_name, gd2->disk_name,
                       b1->tuple_size, b2->tuple_size);
                return -1;
        }
 
        if (b1->tag_size && b2->tag_size && (b1->tag_size != b2->tag_size)) {
                printk(KERN_ERR "%s: %s/%s tag sz %u != %u\n", __func__,
-                      bd1->bd_disk->disk_name, bd2->bd_disk->disk_name,
+                      gd1->disk_name, gd2->disk_name,
                       b1->tag_size, b2->tag_size);
                return -1;
        }
 
        if (strcmp(b1->name, b2->name)) {
                printk(KERN_ERR "%s: %s/%s type %s != %s\n", __func__,
-                      bd1->bd_disk->disk_name, bd2->bd_disk->disk_name,
+                      gd1->disk_name, gd2->disk_name,
                       b1->name, b2->name);
                return -1;
        }
@@ -331,7 +331,8 @@ int blk_integrity_register(struct gendisk *disk, struct blk_integrity *template)
                        return -1;
 
                if (kobject_init_and_add(&bi->kobj, &integrity_ktype,
-                                        &disk->dev.kobj, "%s", "integrity")) {
+                                        &disk_to_dev(disk)->kobj,
+                                        "%s", "integrity")) {
                        kmem_cache_free(integrity_cachep, bi);
                        return -1;
                }
@@ -375,7 +376,7 @@ void blk_integrity_unregister(struct gendisk *disk)
 
        kobject_uevent(&bi->kobj, KOBJ_REMOVE);
        kobject_del(&bi->kobj);
-       kobject_put(&disk->dev.kobj);
        kmem_cache_free(integrity_cachep, bi);
+       disk->integrity = NULL;
 }
 EXPORT_SYMBOL(blk_integrity_unregister);
index af37e4ae62f5933db45692c81258e5af84c632b4..4849fa36161eb697b47b08efa27af085b58bed3c 100644 (file)
@@ -41,10 +41,10 @@ static int __blk_rq_unmap_user(struct bio *bio)
 }
 
 static int __blk_rq_map_user(struct request_queue *q, struct request *rq,
-                            void __user *ubuf, unsigned int len)
+                            struct rq_map_data *map_data, void __user *ubuf,
+                            unsigned int len, int null_mapped, gfp_t gfp_mask)
 {
        unsigned long uaddr;
-       unsigned int alignment;
        struct bio *bio, *orig_bio;
        int reading, ret;
 
@@ -55,15 +55,17 @@ static int __blk_rq_map_user(struct request_queue *q, struct request *rq,
         * direct dma. else, set up kernel bounce buffers
         */
        uaddr = (unsigned long) ubuf;
-       alignment = queue_dma_alignment(q) | q->dma_pad_mask;
-       if (!(uaddr & alignment) && !(len & alignment))
-               bio = bio_map_user(q, NULL, uaddr, len, reading);
+       if (blk_rq_aligned(q, ubuf, len) && !map_data)
+               bio = bio_map_user(q, NULL, uaddr, len, reading, gfp_mask);
        else
-               bio = bio_copy_user(q, uaddr, len, reading);
+               bio = bio_copy_user(q, map_data, uaddr, len, reading, gfp_mask);
 
        if (IS_ERR(bio))
                return PTR_ERR(bio);
 
+       if (null_mapped)
+               bio->bi_flags |= (1 << BIO_NULL_MAPPED);
+
        orig_bio = bio;
        blk_queue_bounce(q, &bio);
 
@@ -85,17 +87,19 @@ static int __blk_rq_map_user(struct request_queue *q, struct request *rq,
 }
 
 /**
- * blk_rq_map_user - map user data to a request, for REQ_BLOCK_PC usage
+ * blk_rq_map_user - map user data to a request, for REQ_TYPE_BLOCK_PC usage
  * @q:         request queue where request should be inserted
  * @rq:                request structure to fill
+ * @map_data:   pointer to the rq_map_data holding pages (if necessary)
  * @ubuf:      the user buffer
  * @len:       length of user data
+ * @gfp_mask:  memory allocation flags
  *
  * Description:
- *    Data will be mapped directly for zero copy io, if possible. Otherwise
+ *    Data will be mapped directly for zero copy I/O, if possible. Otherwise
  *    a kernel bounce buffer is used.
  *
- *    A matching blk_rq_unmap_user() must be issued at the end of io, while
+ *    A matching blk_rq_unmap_user() must be issued at the end of I/O, while
  *    still in process context.
  *
  *    Note: The mapped bio may need to be bounced through blk_queue_bounce()
@@ -105,16 +109,22 @@ static int __blk_rq_map_user(struct request_queue *q, struct request *rq,
  *    unmapping.
  */
 int blk_rq_map_user(struct request_queue *q, struct request *rq,
-                   void __user *ubuf, unsigned long len)
+                   struct rq_map_data *map_data, void __user *ubuf,
+                   unsigned long len, gfp_t gfp_mask)
 {
        unsigned long bytes_read = 0;
        struct bio *bio = NULL;
-       int ret;
+       int ret, null_mapped = 0;
 
        if (len > (q->max_hw_sectors << 9))
                return -EINVAL;
-       if (!len || !ubuf)
+       if (!len)
                return -EINVAL;
+       if (!ubuf) {
+               if (!map_data || rq_data_dir(rq) != READ)
+                       return -EINVAL;
+               null_mapped = 1;
+       }
 
        while (bytes_read != len) {
                unsigned long map_len, end, start;
@@ -132,7 +142,8 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq,
                if (end - start > BIO_MAX_PAGES)
                        map_len -= PAGE_SIZE;
 
-               ret = __blk_rq_map_user(q, rq, ubuf, map_len);
+               ret = __blk_rq_map_user(q, rq, map_data, ubuf, map_len,
+                                       null_mapped, gfp_mask);
                if (ret < 0)
                        goto unmap_rq;
                if (!bio)
@@ -154,18 +165,20 @@ unmap_rq:
 EXPORT_SYMBOL(blk_rq_map_user);
 
 /**
- * blk_rq_map_user_iov - map user data to a request, for REQ_BLOCK_PC usage
+ * blk_rq_map_user_iov - map user data to a request, for REQ_TYPE_BLOCK_PC usage
  * @q:         request queue where request should be inserted
  * @rq:                request to map data to
+ * @map_data:   pointer to the rq_map_data holding pages (if necessary)
  * @iov:       pointer to the iovec
  * @iov_count: number of elements in the iovec
  * @len:       I/O byte count
+ * @gfp_mask:  memory allocation flags
  *
  * Description:
- *    Data will be mapped directly for zero copy io, if possible. Otherwise
+ *    Data will be mapped directly for zero copy I/O, if possible. Otherwise
  *    a kernel bounce buffer is used.
  *
- *    A matching blk_rq_unmap_user() must be issued at the end of io, while
+ *    A matching blk_rq_unmap_user() must be issued at the end of I/O, while
  *    still in process context.
  *
  *    Note: The mapped bio may need to be bounced through blk_queue_bounce()
@@ -175,7 +188,8 @@ EXPORT_SYMBOL(blk_rq_map_user);
  *    unmapping.
  */
 int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
-                       struct sg_iovec *iov, int iov_count, unsigned int len)
+                       struct rq_map_data *map_data, struct sg_iovec *iov,
+                       int iov_count, unsigned int len, gfp_t gfp_mask)
 {
        struct bio *bio;
        int i, read = rq_data_dir(rq) == READ;
@@ -193,10 +207,11 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
                }
        }
 
-       if (unaligned || (q->dma_pad_mask & len))
-               bio = bio_copy_user_iov(q, iov, iov_count, read);
+       if (unaligned || (q->dma_pad_mask & len) || map_data)
+               bio = bio_copy_user_iov(q, map_data, iov, iov_count, read,
+                                       gfp_mask);
        else
-               bio = bio_map_user_iov(q, NULL, iov, iov_count, read);
+               bio = bio_map_user_iov(q, NULL, iov, iov_count, read, gfp_mask);
 
        if (IS_ERR(bio))
                return PTR_ERR(bio);
@@ -216,6 +231,7 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
        rq->buffer = rq->data = NULL;
        return 0;
 }
+EXPORT_SYMBOL(blk_rq_map_user_iov);
 
 /**
  * blk_rq_unmap_user - unmap a request with user data
@@ -224,7 +240,7 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
  * Description:
  *    Unmap a rq previously mapped by blk_rq_map_user(). The caller must
  *    supply the original rq->bio from the blk_rq_map_user() return, since
- *    the io completion may have changed rq->bio.
+ *    the I/O completion may have changed rq->bio.
  */
 int blk_rq_unmap_user(struct bio *bio)
 {
@@ -250,7 +266,7 @@ int blk_rq_unmap_user(struct bio *bio)
 EXPORT_SYMBOL(blk_rq_unmap_user);
 
 /**
- * blk_rq_map_kern - map kernel data to a request, for REQ_BLOCK_PC usage
+ * blk_rq_map_kern - map kernel data to a request, for REQ_TYPE_BLOCK_PC usage
  * @q:         request queue where request should be inserted
  * @rq:                request to fill
  * @kbuf:      the kernel buffer
@@ -264,8 +280,6 @@ EXPORT_SYMBOL(blk_rq_unmap_user);
 int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf,
                    unsigned int len, gfp_t gfp_mask)
 {
-       unsigned long kaddr;
-       unsigned int alignment;
        int reading = rq_data_dir(rq) == READ;
        int do_copy = 0;
        struct bio *bio;
@@ -275,11 +289,7 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf,
        if (!len || !kbuf)
                return -EINVAL;
 
-       kaddr = (unsigned long)kbuf;
-       alignment = queue_dma_alignment(q) | q->dma_pad_mask;
-       do_copy = ((kaddr & alignment) || (len & alignment) ||
-                  object_is_on_stack(kbuf));
-
+       do_copy = !blk_rq_aligned(q, kbuf, len) || object_is_on_stack(kbuf);
        if (do_copy)
                bio = bio_copy_kern(q, kbuf, len, gfp_mask, reading);
        else
index 5efc9e7a68b777fe42cc53b2a7bf3add00adff2a..908d3e11ac523e032f3f73a91932eb49f1a5994a 100644 (file)
@@ -11,7 +11,7 @@
 
 void blk_recalc_rq_sectors(struct request *rq, int nsect)
 {
-       if (blk_fs_request(rq)) {
+       if (blk_fs_request(rq) || blk_discard_rq(rq)) {
                rq->hard_sector += nsect;
                rq->hard_nr_sectors -= nsect;
 
@@ -41,12 +41,9 @@ void blk_recalc_rq_sectors(struct request *rq, int nsect)
 void blk_recalc_rq_segments(struct request *rq)
 {
        int nr_phys_segs;
-       int nr_hw_segs;
        unsigned int phys_size;
-       unsigned int hw_size;
        struct bio_vec *bv, *bvprv = NULL;
        int seg_size;
-       int hw_seg_size;
        int cluster;
        struct req_iterator iter;
        int high, highprv = 1;
@@ -56,8 +53,8 @@ void blk_recalc_rq_segments(struct request *rq)
                return;
 
        cluster = test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
-       hw_seg_size = seg_size = 0;
-       phys_size = hw_size = nr_phys_segs = nr_hw_segs = 0;
+       seg_size = 0;
+       phys_size = nr_phys_segs = 0;
        rq_for_each_segment(bv, rq, iter) {
                /*
                 * the trick here is making sure that a high page is never
@@ -66,7 +63,7 @@ void blk_recalc_rq_segments(struct request *rq)
                 */
                high = page_to_pfn(bv->bv_page) > q->bounce_pfn;
                if (high || highprv)
-                       goto new_hw_segment;
+                       goto new_segment;
                if (cluster) {
                        if (seg_size + bv->bv_len > q->max_segment_size)
                                goto new_segment;
@@ -74,40 +71,19 @@ void blk_recalc_rq_segments(struct request *rq)
                                goto new_segment;
                        if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bv))
                                goto new_segment;
-                       if (BIOVEC_VIRT_OVERSIZE(hw_seg_size + bv->bv_len))
-                               goto new_hw_segment;
 
                        seg_size += bv->bv_len;
-                       hw_seg_size += bv->bv_len;
                        bvprv = bv;
                        continue;
                }
 new_segment:
-               if (BIOVEC_VIRT_MERGEABLE(bvprv, bv) &&
-                   !BIOVEC_VIRT_OVERSIZE(hw_seg_size + bv->bv_len))
-                       hw_seg_size += bv->bv_len;
-               else {
-new_hw_segment:
-                       if (nr_hw_segs == 1 &&
-                           hw_seg_size > rq->bio->bi_hw_front_size)
-                               rq->bio->bi_hw_front_size = hw_seg_size;
-                       hw_seg_size = BIOVEC_VIRT_START_SIZE(bv) + bv->bv_len;
-                       nr_hw_segs++;
-               }
-
                nr_phys_segs++;
                bvprv = bv;
                seg_size = bv->bv_len;
                highprv = high;
        }
 
-       if (nr_hw_segs == 1 &&
-           hw_seg_size > rq->bio->bi_hw_front_size)
-               rq->bio->bi_hw_front_size = hw_seg_size;
-       if (hw_seg_size > rq->biotail->bi_hw_back_size)
-               rq->biotail->bi_hw_back_size = hw_seg_size;
        rq->nr_phys_segments = nr_phys_segs;
-       rq->nr_hw_segments = nr_hw_segs;
 }
 
 void blk_recount_segments(struct request_queue *q, struct bio *bio)
@@ -120,7 +96,6 @@ void blk_recount_segments(struct request_queue *q, struct bio *bio)
        blk_recalc_rq_segments(&rq);
        bio->bi_next = nxt;
        bio->bi_phys_segments = rq.nr_phys_segments;
-       bio->bi_hw_segments = rq.nr_hw_segments;
        bio->bi_flags |= (1 << BIO_SEG_VALID);
 }
 EXPORT_SYMBOL(blk_recount_segments);
@@ -131,13 +106,17 @@ static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio,
        if (!test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags))
                return 0;
 
-       if (!BIOVEC_PHYS_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt)))
-               return 0;
        if (bio->bi_size + nxt->bi_size > q->max_segment_size)
                return 0;
 
+       if (!bio_has_data(bio))
+               return 1;
+
+       if (!BIOVEC_PHYS_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt)))
+               return 0;
+
        /*
-        * bio and nxt are contigous in memory, check if the queue allows
+        * bio and nxt are contiguous in memory; check if the queue allows
         * these two to be merged into one
         */
        if (BIO_SEG_BOUNDARY(q, bio, nxt))
@@ -146,22 +125,6 @@ static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio,
        return 0;
 }
 
-static int blk_hw_contig_segment(struct request_queue *q, struct bio *bio,
-                                struct bio *nxt)
-{
-       if (!bio_flagged(bio, BIO_SEG_VALID))
-               blk_recount_segments(q, bio);
-       if (!bio_flagged(nxt, BIO_SEG_VALID))
-               blk_recount_segments(q, nxt);
-       if (!BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt)) ||
-           BIOVEC_VIRT_OVERSIZE(bio->bi_hw_back_size + nxt->bi_hw_front_size))
-               return 0;
-       if (bio->bi_hw_back_size + nxt->bi_hw_front_size > q->max_segment_size)
-               return 0;
-
-       return 1;
-}
-
 /*
  * map a request to scatterlist, return number of sg entries setup. Caller
  * must make sure sg can hold rq->nr_phys_segments entries
@@ -275,10 +238,9 @@ static inline int ll_new_hw_segment(struct request_queue *q,
                                    struct request *req,
                                    struct bio *bio)
 {
-       int nr_hw_segs = bio_hw_segments(q, bio);
        int nr_phys_segs = bio_phys_segments(q, bio);
 
-       if (req->nr_hw_segments + nr_hw_segs > q->max_hw_segments
+       if (req->nr_phys_segments + nr_phys_segs > q->max_hw_segments
            || req->nr_phys_segments + nr_phys_segs > q->max_phys_segments) {
                req->cmd_flags |= REQ_NOMERGE;
                if (req == q->last_merge)
@@ -290,7 +252,6 @@ static inline int ll_new_hw_segment(struct request_queue *q,
         * This will form the start of a new hw segment.  Bump both
         * counters.
         */
-       req->nr_hw_segments += nr_hw_segs;
        req->nr_phys_segments += nr_phys_segs;
        return 1;
 }
@@ -299,7 +260,6 @@ int ll_back_merge_fn(struct request_queue *q, struct request *req,
                     struct bio *bio)
 {
        unsigned short max_sectors;
-       int len;
 
        if (unlikely(blk_pc_request(req)))
                max_sectors = q->max_hw_sectors;
@@ -316,19 +276,6 @@ int ll_back_merge_fn(struct request_queue *q, struct request *req,
                blk_recount_segments(q, req->biotail);
        if (!bio_flagged(bio, BIO_SEG_VALID))
                blk_recount_segments(q, bio);
-       len = req->biotail->bi_hw_back_size + bio->bi_hw_front_size;
-       if (BIOVEC_VIRT_MERGEABLE(__BVEC_END(req->biotail), __BVEC_START(bio))
-           && !BIOVEC_VIRT_OVERSIZE(len)) {
-               int mergeable =  ll_new_mergeable(q, req, bio);
-
-               if (mergeable) {
-                       if (req->nr_hw_segments == 1)
-                               req->bio->bi_hw_front_size = len;
-                       if (bio->bi_hw_segments == 1)
-                               bio->bi_hw_back_size = len;
-               }
-               return mergeable;
-       }
 
        return ll_new_hw_segment(q, req, bio);
 }
@@ -337,7 +284,6 @@ int ll_front_merge_fn(struct request_queue *q, struct request *req,
                      struct bio *bio)
 {
        unsigned short max_sectors;
-       int len;
 
        if (unlikely(blk_pc_request(req)))
                max_sectors = q->max_hw_sectors;
@@ -351,23 +297,10 @@ int ll_front_merge_fn(struct request_queue *q, struct request *req,
                        q->last_merge = NULL;
                return 0;
        }
-       len = bio->bi_hw_back_size + req->bio->bi_hw_front_size;
        if (!bio_flagged(bio, BIO_SEG_VALID))
                blk_recount_segments(q, bio);
        if (!bio_flagged(req->bio, BIO_SEG_VALID))
                blk_recount_segments(q, req->bio);
-       if (BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(req->bio)) &&
-           !BIOVEC_VIRT_OVERSIZE(len)) {
-               int mergeable =  ll_new_mergeable(q, req, bio);
-
-               if (mergeable) {
-                       if (bio->bi_hw_segments == 1)
-                               bio->bi_hw_front_size = len;
-                       if (req->nr_hw_segments == 1)
-                               req->biotail->bi_hw_back_size = len;
-               }
-               return mergeable;
-       }
 
        return ll_new_hw_segment(q, req, bio);
 }
@@ -376,7 +309,6 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
                                struct request *next)
 {
        int total_phys_segments;
-       int total_hw_segments;
 
        /*
         * First check if the either of the requests are re-queued
@@ -398,26 +330,11 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
        if (total_phys_segments > q->max_phys_segments)
                return 0;
 
-       total_hw_segments = req->nr_hw_segments + next->nr_hw_segments;
-       if (blk_hw_contig_segment(q, req->biotail, next->bio)) {
-               int len = req->biotail->bi_hw_back_size +
-                               next->bio->bi_hw_front_size;
-               /*
-                * propagate the combined length to the end of the requests
-                */
-               if (req->nr_hw_segments == 1)
-                       req->bio->bi_hw_front_size = len;
-               if (next->nr_hw_segments == 1)
-                       next->biotail->bi_hw_back_size = len;
-               total_hw_segments--;
-       }
-
-       if (total_hw_segments > q->max_hw_segments)
+       if (total_phys_segments > q->max_hw_segments)
                return 0;
 
        /* Merge is OK... */
        req->nr_phys_segments = total_phys_segments;
-       req->nr_hw_segments = total_hw_segments;
        return 1;
 }
 
@@ -470,17 +387,21 @@ static int attempt_merge(struct request_queue *q, struct request *req,
        elv_merge_requests(q, req, next);
 
        if (req->rq_disk) {
-               struct hd_struct *part
-                       = get_part(req->rq_disk, req->sector);
-               disk_round_stats(req->rq_disk);
-               req->rq_disk->in_flight--;
-               if (part) {
-                       part_round_stats(part);
-                       part->in_flight--;
-               }
+               struct hd_struct *part;
+               int cpu;
+
+               cpu = part_stat_lock();
+               part = disk_map_sector_rcu(req->rq_disk, req->sector);
+
+               part_round_stats(cpu, part);
+               part_dec_in_flight(part);
+
+               part_stat_unlock();
        }
 
        req->ioprio = ioprio_best(req->ioprio, next->ioprio);
+       if (blk_rq_cpu_valid(next))
+               req->cpu = next->cpu;
 
        __blk_put_request(q, next);
        return 1;
index dfc77012843ffbf9e67fa8996d40099f2db667fe..b21dcdb64151abd31a5cc66ff11db955b0e90a80 100644 (file)
@@ -32,6 +32,23 @@ void blk_queue_prep_rq(struct request_queue *q, prep_rq_fn *pfn)
 }
 EXPORT_SYMBOL(blk_queue_prep_rq);
 
+/**
+ * blk_queue_set_discard - set a discard_sectors function for queue
+ * @q:         queue
+ * @dfn:       prepare_discard function
+ *
+ * It's possible for a queue to register a discard callback which is used
+ * to transform a discard request into the appropriate type for the
+ * hardware. If none is registered, then discard requests are failed
+ * with %EOPNOTSUPP.
+ *
+ */
+void blk_queue_set_discard(struct request_queue *q, prepare_discard_fn *dfn)
+{
+       q->prepare_discard_fn = dfn;
+}
+EXPORT_SYMBOL(blk_queue_set_discard);
+
 /**
  * blk_queue_merge_bvec - set a merge_bvec function for queue
  * @q:         queue
@@ -60,6 +77,24 @@ void blk_queue_softirq_done(struct request_queue *q, softirq_done_fn *fn)
 }
 EXPORT_SYMBOL(blk_queue_softirq_done);
 
+void blk_queue_rq_timeout(struct request_queue *q, unsigned int timeout)
+{
+       q->rq_timeout = timeout;
+}
+EXPORT_SYMBOL_GPL(blk_queue_rq_timeout);
+
+void blk_queue_rq_timed_out(struct request_queue *q, rq_timed_out_fn *fn)
+{
+       q->rq_timed_out_fn = fn;
+}
+EXPORT_SYMBOL_GPL(blk_queue_rq_timed_out);
+
+void blk_queue_lld_busy(struct request_queue *q, lld_busy_fn *fn)
+{
+       q->lld_busy_fn = fn;
+}
+EXPORT_SYMBOL_GPL(blk_queue_lld_busy);
+
 /**
  * blk_queue_make_request - define an alternate make_request function for a device
  * @q:  the request queue for the device to be affected
@@ -127,7 +162,7 @@ EXPORT_SYMBOL(blk_queue_make_request);
  *    Different hardware can have different requirements as to what pages
  *    it can do I/O directly to. A low level driver can call
  *    blk_queue_bounce_limit to have lower memory pages allocated as bounce
- *    buffers for doing I/O to pages residing above @page.
+ *    buffers for doing I/O to pages residing above @dma_addr.
  **/
 void blk_queue_bounce_limit(struct request_queue *q, u64 dma_addr)
 {
@@ -212,7 +247,7 @@ EXPORT_SYMBOL(blk_queue_max_phys_segments);
  * Description:
  *    Enables a low level driver to set an upper limit on the number of
  *    hw data segments in a request.  This would be the largest number of
- *    address/length pairs the host adapter can actually give as once
+ *    address/length pairs the host adapter can actually give at once
  *    to the device.
  **/
 void blk_queue_max_hw_segments(struct request_queue *q,
@@ -393,7 +428,7 @@ EXPORT_SYMBOL(blk_queue_segment_boundary);
  * @mask:  alignment mask
  *
  * description:
- *    set required memory and length aligment for direct dma transactions.
+ *    set required memory and length alignment for direct dma transactions.
  *    this is used when buiding direct io requests for the queue.
  *
  **/
@@ -409,7 +444,7 @@ EXPORT_SYMBOL(blk_queue_dma_alignment);
  * @mask:  alignment mask
  *
  * description:
- *    update required memory and length aligment for direct dma transactions.
+ *    update required memory and length alignment for direct dma transactions.
  *    If the requested alignment is larger than the current alignment, then
  *    the current queue alignment is updated to the new value, otherwise it
  *    is left alone.  The design of this is to allow multiple objects
diff --git a/block/blk-softirq.c b/block/blk-softirq.c
new file mode 100644 (file)
index 0000000..e660d26
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * Functions related to softirq rq completions
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/bio.h>
+#include <linux/blkdev.h>
+#include <linux/interrupt.h>
+#include <linux/cpu.h>
+
+#include "blk.h"
+
+static DEFINE_PER_CPU(struct list_head, blk_cpu_done);
+
+/*
+ * Softirq action handler - move entries to local list and loop over them
+ * while passing them to the queue registered handler.
+ */
+static void blk_done_softirq(struct softirq_action *h)
+{
+       struct list_head *cpu_list, local_list;
+
+       local_irq_disable();
+       cpu_list = &__get_cpu_var(blk_cpu_done);
+       list_replace_init(cpu_list, &local_list);
+       local_irq_enable();
+
+       while (!list_empty(&local_list)) {
+               struct request *rq;
+
+               rq = list_entry(local_list.next, struct request, csd.list);
+               list_del_init(&rq->csd.list);
+               rq->q->softirq_done_fn(rq);
+       }
+}
+
+#if defined(CONFIG_SMP) && defined(CONFIG_USE_GENERIC_SMP_HELPERS)
+static void trigger_softirq(void *data)
+{
+       struct request *rq = data;
+       unsigned long flags;
+       struct list_head *list;
+
+       local_irq_save(flags);
+       list = &__get_cpu_var(blk_cpu_done);
+       list_add_tail(&rq->csd.list, list);
+
+       if (list->next == &rq->csd.list)
+               raise_softirq_irqoff(BLOCK_SOFTIRQ);
+
+       local_irq_restore(flags);
+}
+
+/*
+ * Setup and invoke a run of 'trigger_softirq' on the given cpu.
+ */
+static int raise_blk_irq(int cpu, struct request *rq)
+{
+       if (cpu_online(cpu)) {
+               struct call_single_data *data = &rq->csd;
+
+               data->func = trigger_softirq;
+               data->info = rq;
+               data->flags = 0;
+
+               __smp_call_function_single(cpu, data);
+               return 0;
+       }
+
+       return 1;
+}
+#else /* CONFIG_SMP && CONFIG_USE_GENERIC_SMP_HELPERS */
+static int raise_blk_irq(int cpu, struct request *rq)
+{
+       return 1;
+}
+#endif
+
+static int __cpuinit blk_cpu_notify(struct notifier_block *self,
+                                   unsigned long action, void *hcpu)
+{
+       /*
+        * If a CPU goes away, splice its entries to the current CPU
+        * and trigger a run of the softirq
+        */
+       if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) {
+               int cpu = (unsigned long) hcpu;
+
+               local_irq_disable();
+               list_splice_init(&per_cpu(blk_cpu_done, cpu),
+                                &__get_cpu_var(blk_cpu_done));
+               raise_softirq_irqoff(BLOCK_SOFTIRQ);
+               local_irq_enable();
+       }
+
+       return NOTIFY_OK;
+}
+
+static struct notifier_block __cpuinitdata blk_cpu_notifier = {
+       .notifier_call  = blk_cpu_notify,
+};
+
+void __blk_complete_request(struct request *req)
+{
+       struct request_queue *q = req->q;
+       unsigned long flags;
+       int ccpu, cpu, group_cpu;
+
+       BUG_ON(!q->softirq_done_fn);
+
+       local_irq_save(flags);
+       cpu = smp_processor_id();
+       group_cpu = blk_cpu_to_group(cpu);
+
+       /*
+        * Select completion CPU
+        */
+       if (test_bit(QUEUE_FLAG_SAME_COMP, &q->queue_flags) && req->cpu != -1)
+               ccpu = req->cpu;
+       else
+               ccpu = cpu;
+
+       if (ccpu == cpu || ccpu == group_cpu) {
+               struct list_head *list;
+do_local:
+               list = &__get_cpu_var(blk_cpu_done);
+               list_add_tail(&req->csd.list, list);
+
+               /*
+                * if the list only contains our just added request,
+                * signal a raise of the softirq. If there are already
+                * entries there, someone already raised the irq but it
+                * hasn't run yet.
+                */
+               if (list->next == &req->csd.list)
+                       raise_softirq_irqoff(BLOCK_SOFTIRQ);
+       } else if (raise_blk_irq(ccpu, req))
+               goto do_local;
+
+       local_irq_restore(flags);
+}
+
+/**
+ * blk_complete_request - end I/O on a request
+ * @req:      the request being processed
+ *
+ * Description:
+ *     Ends all I/O on a request. It does not handle partial completions,
+ *     unless the driver actually implements this in its completion callback
+ *     through requeueing. The actual completion happens out-of-order,
+ *     through a softirq handler. The user must have registered a completion
+ *     callback through blk_queue_softirq_done().
+ **/
+void blk_complete_request(struct request *req)
+{
+       if (unlikely(blk_should_fake_timeout(req->q)))
+               return;
+       if (!blk_mark_rq_complete(req))
+               __blk_complete_request(req);
+}
+EXPORT_SYMBOL(blk_complete_request);
+
+__init int blk_softirq_init(void)
+{
+       int i;
+
+       for_each_possible_cpu(i)
+               INIT_LIST_HEAD(&per_cpu(blk_cpu_done, i));
+
+       open_softirq(BLOCK_SOFTIRQ, blk_done_softirq);
+       register_hotcpu_notifier(&blk_cpu_notifier);
+       return 0;
+}
+subsys_initcall(blk_softirq_init);
index 304ec73ab8215f270cbea1a50e870fd8b5b7bf54..21e275d7eed9444ab876834db2345eb78f4ae183 100644 (file)
@@ -156,6 +156,30 @@ static ssize_t queue_nomerges_store(struct request_queue *q, const char *page,
        return ret;
 }
 
+static ssize_t queue_rq_affinity_show(struct request_queue *q, char *page)
+{
+       unsigned int set = test_bit(QUEUE_FLAG_SAME_COMP, &q->queue_flags);
+
+       return queue_var_show(set != 0, page);
+}
+
+static ssize_t
+queue_rq_affinity_store(struct request_queue *q, const char *page, size_t count)
+{
+       ssize_t ret = -EINVAL;
+#if defined(CONFIG_USE_GENERIC_SMP_HELPERS)
+       unsigned long val;
+
+       ret = queue_var_store(&val, page, count);
+       spin_lock_irq(q->queue_lock);
+       if (val)
+               queue_flag_set(QUEUE_FLAG_SAME_COMP, q);
+       else
+               queue_flag_clear(QUEUE_FLAG_SAME_COMP,  q);
+       spin_unlock_irq(q->queue_lock);
+#endif
+       return ret;
+}
 
 static struct queue_sysfs_entry queue_requests_entry = {
        .attr = {.name = "nr_requests", .mode = S_IRUGO | S_IWUSR },
@@ -197,6 +221,12 @@ static struct queue_sysfs_entry queue_nomerges_entry = {
        .store = queue_nomerges_store,
 };
 
+static struct queue_sysfs_entry queue_rq_affinity_entry = {
+       .attr = {.name = "rq_affinity", .mode = S_IRUGO | S_IWUSR },
+       .show = queue_rq_affinity_show,
+       .store = queue_rq_affinity_store,
+};
+
 static struct attribute *default_attrs[] = {
        &queue_requests_entry.attr,
        &queue_ra_entry.attr,
@@ -205,6 +235,7 @@ static struct attribute *default_attrs[] = {
        &queue_iosched_entry.attr,
        &queue_hw_sector_size_entry.attr,
        &queue_nomerges_entry.attr,
+       &queue_rq_affinity_entry.attr,
        NULL,
 };
 
@@ -310,7 +341,7 @@ int blk_register_queue(struct gendisk *disk)
        if (!q->request_fn)
                return 0;
 
-       ret = kobject_add(&q->kobj, kobject_get(&disk->dev.kobj),
+       ret = kobject_add(&q->kobj, kobject_get(&disk_to_dev(disk)->kobj),
                          "%s", "queue");
        if (ret < 0)
                return ret;
@@ -339,6 +370,6 @@ void blk_unregister_queue(struct gendisk *disk)
 
                kobject_uevent(&q->kobj, KOBJ_REMOVE);
                kobject_del(&q->kobj);
-               kobject_put(&disk->dev.kobj);
+               kobject_put(&disk_to_dev(disk)->kobj);
        }
 }
index ed5166fbc599ab0fca60955a200028ad0de8a5ae..c0d419e84ce7f8518e1246e3ec61b07f5c81efe8 100644 (file)
@@ -29,7 +29,7 @@ EXPORT_SYMBOL(blk_queue_find_tag);
  * __blk_free_tags - release a given set of tag maintenance info
  * @bqt:       the tag map to free
  *
- * Tries to free the specified @bqt@.  Returns true if it was
+ * Tries to free the specified @bqt.  Returns true if it was
  * actually freed and false if there are still references using it
  */
 static int __blk_free_tags(struct blk_queue_tag *bqt)
@@ -78,7 +78,7 @@ void __blk_queue_free_tags(struct request_queue *q)
  * blk_free_tags - release a given set of tag maintenance info
  * @bqt:       the tag map to free
  *
- * For externally managed @bqt@ frees the map.  Callers of this
+ * For externally managed @bqt frees the map.  Callers of this
  * function must guarantee to have released all the queues that
  * might have been using this tag map.
  */
@@ -94,7 +94,7 @@ EXPORT_SYMBOL(blk_free_tags);
  * @q:  the request queue for the device
  *
  *  Notes:
- *     This is used to disabled tagged queuing to a device, yet leave
+ *     This is used to disable tagged queuing to a device, yet leave
  *     queue in function.
  **/
 void blk_queue_free_tags(struct request_queue *q)
@@ -271,7 +271,7 @@ EXPORT_SYMBOL(blk_queue_resize_tags);
  * @rq: the request that has completed
  *
  *  Description:
- *    Typically called when end_that_request_first() returns 0, meaning
+ *    Typically called when end_that_request_first() returns %0, meaning
  *    all transfers have been done for a request. It's important to call
  *    this function before end_that_request_last(), as that will put the
  *    request back on the free list thus corrupting the internal tag list.
@@ -337,6 +337,7 @@ EXPORT_SYMBOL(blk_queue_end_tag);
 int blk_queue_start_tag(struct request_queue *q, struct request *rq)
 {
        struct blk_queue_tag *bqt = q->queue_tags;
+       unsigned max_depth, offset;
        int tag;
 
        if (unlikely((rq->cmd_flags & REQ_QUEUED))) {
@@ -350,10 +351,19 @@ int blk_queue_start_tag(struct request_queue *q, struct request *rq)
        /*
         * Protect against shared tag maps, as we may not have exclusive
         * access to the tag map.
+        *
+        * We reserve a few tags just for sync IO, since we don't want
+        * to starve sync IO on behalf of flooding async IO.
         */
+       max_depth = bqt->max_depth;
+       if (rq_is_sync(rq))
+               offset = 0;
+       else
+               offset = max_depth >> 2;
+
        do {
-               tag = find_first_zero_bit(bqt->tag_map, bqt->max_depth);
-               if (tag >= bqt->max_depth)
+               tag = find_next_zero_bit(bqt->tag_map, max_depth, offset);
+               if (tag >= max_depth)
                        return 1;
 
        } while (test_and_set_bit_lock(tag, bqt->tag_map));
diff --git a/block/blk-timeout.c b/block/blk-timeout.c
new file mode 100644 (file)
index 0000000..972a63f
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * Functions related to generic timeout handling of requests.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/blkdev.h>
+#include <linux/fault-inject.h>
+
+#include "blk.h"
+
+#ifdef CONFIG_FAIL_IO_TIMEOUT
+
+static DECLARE_FAULT_ATTR(fail_io_timeout);
+
+static int __init setup_fail_io_timeout(char *str)
+{
+       return setup_fault_attr(&fail_io_timeout, str);
+}
+__setup("fail_io_timeout=", setup_fail_io_timeout);
+
+int blk_should_fake_timeout(struct request_queue *q)
+{
+       if (!test_bit(QUEUE_FLAG_FAIL_IO, &q->queue_flags))
+               return 0;
+
+       return should_fail(&fail_io_timeout, 1);
+}
+
+static int __init fail_io_timeout_debugfs(void)
+{
+       return init_fault_attr_dentries(&fail_io_timeout, "fail_io_timeout");
+}
+
+late_initcall(fail_io_timeout_debugfs);
+
+ssize_t part_timeout_show(struct device *dev, struct device_attribute *attr,
+                         char *buf)
+{
+       struct gendisk *disk = dev_to_disk(dev);
+       int set = test_bit(QUEUE_FLAG_FAIL_IO, &disk->queue->queue_flags);
+
+       return sprintf(buf, "%d\n", set != 0);
+}
+
+ssize_t part_timeout_store(struct device *dev, struct device_attribute *attr,
+                          const char *buf, size_t count)
+{
+       struct gendisk *disk = dev_to_disk(dev);
+       int val;
+
+       if (count) {
+               struct request_queue *q = disk->queue;
+               char *p = (char *) buf;
+
+               val = simple_strtoul(p, &p, 10);
+               spin_lock_irq(q->queue_lock);
+               if (val)
+                       queue_flag_set(QUEUE_FLAG_FAIL_IO, q);
+               else
+                       queue_flag_clear(QUEUE_FLAG_FAIL_IO, q);
+               spin_unlock_irq(q->queue_lock);
+       }
+
+       return count;
+}
+
+#endif /* CONFIG_FAIL_IO_TIMEOUT */
+
+/*
+ * blk_delete_timer - Delete/cancel timer for a given function.
+ * @req:       request that we are canceling timer for
+ *
+ */
+void blk_delete_timer(struct request *req)
+{
+       struct request_queue *q = req->q;
+
+       /*
+        * Nothing to detach
+        */
+       if (!q->rq_timed_out_fn || !req->deadline)
+               return;
+
+       list_del_init(&req->timeout_list);
+
+       if (list_empty(&q->timeout_list))
+               del_timer(&q->timeout);
+}
+
+static void blk_rq_timed_out(struct request *req)
+{
+       struct request_queue *q = req->q;
+       enum blk_eh_timer_return ret;
+
+       ret = q->rq_timed_out_fn(req);
+       switch (ret) {
+       case BLK_EH_HANDLED:
+               __blk_complete_request(req);
+               break;
+       case BLK_EH_RESET_TIMER:
+               blk_clear_rq_complete(req);
+               blk_add_timer(req);
+               break;
+       case BLK_EH_NOT_HANDLED:
+               /*
+                * LLD handles this for now but in the future
+                * we can send a request msg to abort the command
+                * and we can move more of the generic scsi eh code to
+                * the blk layer.
+                */
+               break;
+       default:
+               printk(KERN_ERR "block: bad eh return: %d\n", ret);
+               break;
+       }
+}
+
+void blk_rq_timed_out_timer(unsigned long data)
+{
+       struct request_queue *q = (struct request_queue *) data;
+       unsigned long flags, uninitialized_var(next), next_set = 0;
+       struct request *rq, *tmp;
+
+       spin_lock_irqsave(q->queue_lock, flags);
+
+       list_for_each_entry_safe(rq, tmp, &q->timeout_list, timeout_list) {
+               if (time_after_eq(jiffies, rq->deadline)) {
+                       list_del_init(&rq->timeout_list);
+
+                       /*
+                        * Check if we raced with end io completion
+                        */
+                       if (blk_mark_rq_complete(rq))
+                               continue;
+                       blk_rq_timed_out(rq);
+               }
+               if (!next_set) {
+                       next = rq->deadline;
+                       next_set = 1;
+               } else if (time_after(next, rq->deadline))
+                       next = rq->deadline;
+       }
+
+       if (next_set && !list_empty(&q->timeout_list))
+               mod_timer(&q->timeout, round_jiffies(next));
+
+       spin_unlock_irqrestore(q->queue_lock, flags);
+}
+
+/**
+ * blk_abort_request -- Request request recovery for the specified command
+ * @req:       pointer to the request of interest
+ *
+ * This function requests that the block layer start recovery for the
+ * request by deleting the timer and calling the q's timeout function.
+ * LLDDs who implement their own error recovery MAY ignore the timeout
+ * event if they generated blk_abort_req. Must hold queue lock.
+ */
+void blk_abort_request(struct request *req)
+{
+       if (blk_mark_rq_complete(req))
+               return;
+       blk_delete_timer(req);
+       blk_rq_timed_out(req);
+}
+EXPORT_SYMBOL_GPL(blk_abort_request);
+
+/**
+ * blk_add_timer - Start timeout timer for a single request
+ * @req:       request that is about to start running.
+ *
+ * Notes:
+ *    Each request has its own timer, and as it is added to the queue, we
+ *    set up the timer. When the request completes, we cancel the timer.
+ */
+void blk_add_timer(struct request *req)
+{
+       struct request_queue *q = req->q;
+       unsigned long expiry;
+
+       if (!q->rq_timed_out_fn)
+               return;
+
+       BUG_ON(!list_empty(&req->timeout_list));
+       BUG_ON(test_bit(REQ_ATOM_COMPLETE, &req->atomic_flags));
+
+       if (req->timeout)
+               req->deadline = jiffies + req->timeout;
+       else {
+               req->deadline = jiffies + q->rq_timeout;
+               /*
+                * Some LLDs, like scsi, peek at the timeout to prevent
+                * a command from being retried forever.
+                */
+               req->timeout = q->rq_timeout;
+       }
+       list_add_tail(&req->timeout_list, &q->timeout_list);
+
+       /*
+        * If the timer isn't already pending or this timeout is earlier
+        * than an existing one, modify the timer. Round to next nearest
+        * second.
+        */
+       expiry = round_jiffies(req->deadline);
+
+       /*
+        * We use ->deadline == 0 to detect whether a timer was added or
+        * not, so just increase to next jiffy for that specific case
+        */
+       if (unlikely(!req->deadline))
+               req->deadline = 1;
+
+       if (!timer_pending(&q->timeout) ||
+           time_before(expiry, q->timeout.expires))
+               mod_timer(&q->timeout, expiry);
+}
+
+/**
+ * blk_abort_queue -- Abort all request on given queue
+ * @queue:     pointer to queue
+ *
+ */
+void blk_abort_queue(struct request_queue *q)
+{
+       unsigned long flags;
+       struct request *rq, *tmp;
+
+       spin_lock_irqsave(q->queue_lock, flags);
+
+       elv_abort_queue(q);
+
+       list_for_each_entry_safe(rq, tmp, &q->timeout_list, timeout_list)
+               blk_abort_request(rq);
+
+       spin_unlock_irqrestore(q->queue_lock, flags);
+
+}
+EXPORT_SYMBOL_GPL(blk_abort_queue);
index c79f30e1df52d8388c6c89505e97756f2f906098..e5c5797699636332640f7412d82b9f2cb5e07c83 100644 (file)
@@ -17,6 +17,42 @@ void __blk_queue_free_tags(struct request_queue *q);
 
 void blk_unplug_work(struct work_struct *work);
 void blk_unplug_timeout(unsigned long data);
+void blk_rq_timed_out_timer(unsigned long data);
+void blk_delete_timer(struct request *);
+void blk_add_timer(struct request *);
+
+/*
+ * Internal atomic flags for request handling
+ */
+enum rq_atomic_flags {
+       REQ_ATOM_COMPLETE = 0,
+};
+
+/*
+ * EH timer and IO completion will both attempt to 'grab' the request, make
+ * sure that only one of them suceeds
+ */
+static inline int blk_mark_rq_complete(struct request *rq)
+{
+       return test_and_set_bit(REQ_ATOM_COMPLETE, &rq->atomic_flags);
+}
+
+static inline void blk_clear_rq_complete(struct request *rq)
+{
+       clear_bit(REQ_ATOM_COMPLETE, &rq->atomic_flags);
+}
+
+#ifdef CONFIG_FAIL_IO_TIMEOUT
+int blk_should_fake_timeout(struct request_queue *);
+ssize_t part_timeout_show(struct device *, struct device_attribute *, char *);
+ssize_t part_timeout_store(struct device *, struct device_attribute *,
+                               const char *, size_t);
+#else
+static inline int blk_should_fake_timeout(struct request_queue *q)
+{
+       return 0;
+}
+#endif
 
 struct io_context *current_io_context(gfp_t gfp_flags, int node);
 
@@ -59,4 +95,16 @@ static inline int queue_congestion_off_threshold(struct request_queue *q)
 
 #endif /* BLK_DEV_INTEGRITY */
 
+static inline int blk_cpu_to_group(int cpu)
+{
+#ifdef CONFIG_SCHED_MC
+       cpumask_t mask = cpu_coregroup_map(cpu);
+       return first_cpu(mask);
+#elif defined(CONFIG_SCHED_SMT)
+       return first_cpu(per_cpu(cpu_sibling_map, cpu));
+#else
+       return cpu;
+#endif
+}
+
 #endif
index eb9651ccb241c28ce666300c02830ffea65df691..85049a7e7a179a97c283eb4ebe6c1fe7285f80cf 100644 (file)
@@ -111,23 +111,9 @@ static int act_log_check(struct blk_trace *bt, u32 what, sector_t sector,
  */
 static u32 ddir_act[2] __read_mostly = { BLK_TC_ACT(BLK_TC_READ), BLK_TC_ACT(BLK_TC_WRITE) };
 
-/*
- * Bio action bits of interest
- */
-static u32 bio_act[9] __read_mostly = { 0, BLK_TC_ACT(BLK_TC_BARRIER), BLK_TC_ACT(BLK_TC_SYNC), 0, BLK_TC_ACT(BLK_TC_AHEAD), 0, 0, 0, BLK_TC_ACT(BLK_TC_META) };
-
-/*
- * More could be added as needed, taking care to increment the decrementer
- * to get correct indexing
- */
-#define trace_barrier_bit(rw)  \
-       (((rw) & (1 << BIO_RW_BARRIER)) >> (BIO_RW_BARRIER - 0))
-#define trace_sync_bit(rw)     \
-       (((rw) & (1 << BIO_RW_SYNC)) >> (BIO_RW_SYNC - 1))
-#define trace_ahead_bit(rw)    \
-       (((rw) & (1 << BIO_RW_AHEAD)) << (2 - BIO_RW_AHEAD))
-#define trace_meta_bit(rw)     \
-       (((rw) & (1 << BIO_RW_META)) >> (BIO_RW_META - 3))
+/* The ilog2() calls fall out because they're constant */
+#define MASK_TC_BIT(rw, __name) ( (rw & (1 << BIO_RW_ ## __name)) << \
+         (ilog2(BLK_TC_ ## __name) + BLK_TC_SHIFT - BIO_RW_ ## __name) )
 
 /*
  * The worker for the various blk_add_trace*() types. Fills out a
@@ -147,10 +133,11 @@ void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
                return;
 
        what |= ddir_act[rw & WRITE];
-       what |= bio_act[trace_barrier_bit(rw)];
-       what |= bio_act[trace_sync_bit(rw)];
-       what |= bio_act[trace_ahead_bit(rw)];
-       what |= bio_act[trace_meta_bit(rw)];
+       what |= MASK_TC_BIT(rw, BARRIER);
+       what |= MASK_TC_BIT(rw, SYNC);
+       what |= MASK_TC_BIT(rw, AHEAD);
+       what |= MASK_TC_BIT(rw, META);
+       what |= MASK_TC_BIT(rw, DISCARD);
 
        pid = tsk->pid;
        if (unlikely(act_log_check(bt, what, sector, pid)))
@@ -382,7 +369,8 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
        if (!buts->buf_size || !buts->buf_nr)
                return -EINVAL;
 
-       strcpy(buts->name, name);
+       strncpy(buts->name, name, BLKTRACE_BDEV_SIZE);
+       buts->name[BLKTRACE_BDEV_SIZE - 1] = '\0';
 
        /*
         * some device names have larger paths - convert the slashes
index 0aae8d7ba99c432604995ed3b8b907623032c15e..56cb343c76d8d4c507e80a7a08743b695d863756 100644 (file)
@@ -283,7 +283,8 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, int has_write_perm)
                next_rq->cmd_type = rq->cmd_type;
 
                dxferp = (void*)(unsigned long)hdr->din_xferp;
-               ret =  blk_rq_map_user(q, next_rq, dxferp, hdr->din_xfer_len);
+               ret =  blk_rq_map_user(q, next_rq, NULL, dxferp,
+                                      hdr->din_xfer_len, GFP_KERNEL);
                if (ret)
                        goto out;
        }
@@ -298,7 +299,8 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, int has_write_perm)
                dxfer_len = 0;
 
        if (dxfer_len) {
-               ret = blk_rq_map_user(q, rq, dxferp, dxfer_len);
+               ret = blk_rq_map_user(q, rq, NULL, dxferp, dxfer_len,
+                                     GFP_KERNEL);
                if (ret)
                        goto out;
        }
index 1e2aff812ee2b278bd831809269c4d6c76234858..6a062eebbd15301320e7491b5dd45d17f2204a3c 100644 (file)
@@ -39,6 +39,7 @@ static int cfq_slice_idle = HZ / 125;
 #define CFQ_MIN_TT             (2)
 
 #define CFQ_SLICE_SCALE                (5)
+#define CFQ_HW_QUEUE_MIN       (5)
 
 #define RQ_CIC(rq)             \
        ((struct cfq_io_context *) (rq)->elevator_private)
@@ -86,7 +87,14 @@ struct cfq_data {
 
        int rq_in_driver;
        int sync_flight;
+
+       /*
+        * queue-depth detection
+        */
+       int rq_queued;
        int hw_tag;
+       int hw_tag_samples;
+       int rq_in_driver_peak;
 
        /*
         * idle window management
@@ -244,7 +252,7 @@ static inline void cfq_schedule_dispatch(struct cfq_data *cfqd)
 {
        if (cfqd->busy_queues) {
                cfq_log(cfqd, "schedule dispatch");
-               kblockd_schedule_work(&cfqd->unplug_work);
+               kblockd_schedule_work(cfqd->queue, &cfqd->unplug_work);
        }
 }
 
@@ -654,15 +662,6 @@ static void cfq_activate_request(struct request_queue *q, struct request *rq)
        cfq_log_cfqq(cfqd, RQ_CFQQ(rq), "activate rq, drv=%d",
                                                cfqd->rq_in_driver);
 
-       /*
-        * If the depth is larger 1, it really could be queueing. But lets
-        * make the mark a little higher - idling could still be good for
-        * low queueing, and a low queueing number could also just indicate
-        * a SCSI mid layer like behaviour where limit+1 is often seen.
-        */
-       if (!cfqd->hw_tag && cfqd->rq_in_driver > 4)
-               cfqd->hw_tag = 1;
-
        cfqd->last_position = rq->hard_sector + rq->hard_nr_sectors;
 }
 
@@ -686,6 +685,7 @@ static void cfq_remove_request(struct request *rq)
        list_del_init(&rq->queuelist);
        cfq_del_rq_rb(rq);
 
+       cfqq->cfqd->rq_queued--;
        if (rq_is_meta(rq)) {
                WARN_ON(!cfqq->meta_pending);
                cfqq->meta_pending--;
@@ -878,6 +878,14 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
        struct cfq_io_context *cic;
        unsigned long sl;
 
+       /*
+        * SSD device without seek penalty, disable idling. But only do so
+        * for devices that support queuing, otherwise we still have a problem
+        * with sync vs async workloads.
+        */
+       if (blk_queue_nonrot(cfqd->queue) && cfqd->hw_tag)
+               return;
+
        WARN_ON(!RB_EMPTY_ROOT(&cfqq->sort_list));
        WARN_ON(cfq_cfqq_slice_new(cfqq));
 
@@ -1833,6 +1841,7 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq,
 {
        struct cfq_io_context *cic = RQ_CIC(rq);
 
+       cfqd->rq_queued++;
        if (rq_is_meta(rq))
                cfqq->meta_pending++;
 
@@ -1880,6 +1889,31 @@ static void cfq_insert_request(struct request_queue *q, struct request *rq)
        cfq_rq_enqueued(cfqd, cfqq, rq);
 }
 
+/*
+ * Update hw_tag based on peak queue depth over 50 samples under
+ * sufficient load.
+ */
+static void cfq_update_hw_tag(struct cfq_data *cfqd)
+{
+       if (cfqd->rq_in_driver > cfqd->rq_in_driver_peak)
+               cfqd->rq_in_driver_peak = cfqd->rq_in_driver;
+
+       if (cfqd->rq_queued <= CFQ_HW_QUEUE_MIN &&
+           cfqd->rq_in_driver <= CFQ_HW_QUEUE_MIN)
+               return;
+
+       if (cfqd->hw_tag_samples++ < 50)
+               return;
+
+       if (cfqd->rq_in_driver_peak >= CFQ_HW_QUEUE_MIN)
+               cfqd->hw_tag = 1;
+       else
+               cfqd->hw_tag = 0;
+
+       cfqd->hw_tag_samples = 0;
+       cfqd->rq_in_driver_peak = 0;
+}
+
 static void cfq_completed_request(struct request_queue *q, struct request *rq)
 {
        struct cfq_queue *cfqq = RQ_CFQQ(rq);
@@ -1890,6 +1924,8 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq)
        now = jiffies;
        cfq_log_cfqq(cfqd, cfqq, "complete");
 
+       cfq_update_hw_tag(cfqd);
+
        WARN_ON(!cfqd->rq_in_driver);
        WARN_ON(!cfqq->dispatched);
        cfqd->rq_in_driver--;
@@ -2200,6 +2236,7 @@ static void *cfq_init_queue(struct request_queue *q)
        cfqd->cfq_slice[1] = cfq_slice_sync;
        cfqd->cfq_slice_async_rq = cfq_slice_async_rq;
        cfqd->cfq_slice_idle = cfq_slice_idle;
+       cfqd->hw_tag = 1;
 
        return cfqd;
 }
index 79c14996ac110ab1a2cd34af04049df5963a1019..e669aed4c6bcd8896434b7625766d8f2772f2ad3 100644 (file)
@@ -211,14 +211,10 @@ int blk_register_filter(struct gendisk *disk)
 {
        int ret;
        struct blk_cmd_filter *filter = &disk->queue->cmd_filter;
-       struct kobject *parent = kobject_get(disk->holder_dir->parent);
 
-       if (!parent)
-               return -ENODEV;
-
-       ret = kobject_init_and_add(&filter->kobj, &rcf_ktype, parent,
+       ret = kobject_init_and_add(&filter->kobj, &rcf_ktype,
+                                  &disk_to_dev(disk)->kobj,
                                   "%s", "cmd_filter");
-
        if (ret < 0)
                return ret;
 
@@ -231,7 +227,6 @@ void blk_unregister_filter(struct gendisk *disk)
        struct blk_cmd_filter *filter = &disk->queue->cmd_filter;
 
        kobject_put(&filter->kobj);
-       kobject_put(disk->holder_dir->parent);
 }
 EXPORT_SYMBOL(blk_unregister_filter);
 #endif
index c23177e4623f1ba73804479460742dd63339556a..1e559fba7bdfc58859605b0d9fdc879346f86b07 100644 (file)
@@ -788,6 +788,7 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
                return compat_hdio_getgeo(disk, bdev, compat_ptr(arg));
        case BLKFLSBUF:
        case BLKROSET:
+       case BLKDISCARD:
        /*
         * the ones below are implemented in blkdev_locked_ioctl,
         * but we call blkdev_ioctl, which gets the lock for us
index 342448c3d2ddf20432410b121ef3060859c998d3..fd311179f44c771f5c4ca49c2d67b3812fe47eb9 100644 (file)
@@ -33,7 +33,7 @@ struct deadline_data {
         */
        struct rb_root sort_list[2];    
        struct list_head fifo_list[2];
-       
+
        /*
         * next in sort order. read, write or both are NULL
         */
@@ -53,7 +53,11 @@ struct deadline_data {
 
 static void deadline_move_request(struct deadline_data *, struct request *);
 
-#define RQ_RB_ROOT(dd, rq)     (&(dd)->sort_list[rq_data_dir((rq))])
+static inline struct rb_root *
+deadline_rb_root(struct deadline_data *dd, struct request *rq)
+{
+       return &dd->sort_list[rq_data_dir(rq)];
+}
 
 /*
  * get the request after `rq' in sector-sorted order
@@ -72,15 +76,11 @@ deadline_latter_request(struct request *rq)
 static void
 deadline_add_rq_rb(struct deadline_data *dd, struct request *rq)
 {
-       struct rb_root *root = RQ_RB_ROOT(dd, rq);
+       struct rb_root *root = deadline_rb_root(dd, rq);
        struct request *__alias;
 
-retry:
-       __alias = elv_rb_add(root, rq);
-       if (unlikely(__alias)) {
+       while (unlikely(__alias = elv_rb_add(root, rq)))
                deadline_move_request(dd, __alias);
-               goto retry;
-       }
 }
 
 static inline void
@@ -91,7 +91,7 @@ deadline_del_rq_rb(struct deadline_data *dd, struct request *rq)
        if (dd->next_rq[data_dir] == rq)
                dd->next_rq[data_dir] = deadline_latter_request(rq);
 
-       elv_rb_del(RQ_RB_ROOT(dd, rq), rq);
+       elv_rb_del(deadline_rb_root(dd, rq), rq);
 }
 
 /*
@@ -106,7 +106,7 @@ deadline_add_request(struct request_queue *q, struct request *rq)
        deadline_add_rq_rb(dd, rq);
 
        /*
-        * set expire time (only used for reads) and add to fifo list
+        * set expire time and add to fifo list
         */
        rq_set_fifo_time(rq, jiffies + dd->fifo_expire[data_dir]);
        list_add_tail(&rq->queuelist, &dd->fifo_list[data_dir]);
@@ -162,7 +162,7 @@ static void deadline_merged_request(struct request_queue *q,
         * if the merge was a front merge, we need to reposition request
         */
        if (type == ELEVATOR_FRONT_MERGE) {
-               elv_rb_del(RQ_RB_ROOT(dd, req), req);
+               elv_rb_del(deadline_rb_root(dd, req), req);
                deadline_add_rq_rb(dd, req);
        }
 }
@@ -212,7 +212,7 @@ deadline_move_request(struct deadline_data *dd, struct request *rq)
        dd->next_rq[WRITE] = NULL;
        dd->next_rq[data_dir] = deadline_latter_request(rq);
 
-       dd->last_sector = rq->sector + rq->nr_sectors;
+       dd->last_sector = rq_end_sector(rq);
 
        /*
         * take it off the sort and fifo list, move
@@ -222,7 +222,7 @@ deadline_move_request(struct deadline_data *dd, struct request *rq)
 }
 
 /*
- * deadline_check_fifo returns 0 if there are no expired reads on the fifo,
+ * deadline_check_fifo returns 0 if there are no expired requests on the fifo,
  * 1 otherwise. Requires !list_empty(&dd->fifo_list[data_dir])
  */
 static inline int deadline_check_fifo(struct deadline_data *dd, int ddir)
@@ -258,17 +258,9 @@ static int deadline_dispatch_requests(struct request_queue *q, int force)
        else
                rq = dd->next_rq[READ];
 
-       if (rq) {
-               /* we have a "next request" */
-               
-               if (dd->last_sector != rq->sector)
-                       /* end the batch on a non sequential request */
-                       dd->batching += dd->fifo_batch;
-               
-               if (dd->batching < dd->fifo_batch)
-                       /* we are still entitled to batch */
-                       goto dispatch_request;
-       }
+       if (rq && dd->batching < dd->fifo_batch)
+               /* we have a next request are still entitled to batch */
+               goto dispatch_request;
 
        /*
         * at this point we are not running a batch. select the appropriate
index ed6f8f32d27ee8d09f5c3673852d416bad228862..04518921db31bb66c115752d62c2a35df11e98e3 100644 (file)
@@ -34,8 +34,9 @@
 #include <linux/delay.h>
 #include <linux/blktrace_api.h>
 #include <linux/hash.h>
+#include <linux/uaccess.h>
 
-#include <asm/uaccess.h>
+#include "blk.h"
 
 static DEFINE_SPINLOCK(elv_list_lock);
 static LIST_HEAD(elv_list);
@@ -74,6 +75,12 @@ int elv_rq_merge_ok(struct request *rq, struct bio *bio)
        if (!rq_mergeable(rq))
                return 0;
 
+       /*
+        * Don't merge file system requests and discard requests
+        */
+       if (bio_discard(bio) != bio_discard(rq->bio))
+               return 0;
+
        /*
         * different data direction or already started, don't merge
         */
@@ -438,6 +445,8 @@ void elv_dispatch_sort(struct request_queue *q, struct request *rq)
        list_for_each_prev(entry, &q->queue_head) {
                struct request *pos = list_entry_rq(entry);
 
+               if (blk_discard_rq(rq) != blk_discard_rq(pos))
+                       break;
                if (rq_data_dir(rq) != rq_data_dir(pos))
                        break;
                if (pos->cmd_flags & stop_flags)
@@ -607,7 +616,7 @@ void elv_insert(struct request_queue *q, struct request *rq, int where)
                break;
 
        case ELEVATOR_INSERT_SORT:
-               BUG_ON(!blk_fs_request(rq));
+               BUG_ON(!blk_fs_request(rq) && !blk_discard_rq(rq));
                rq->cmd_flags |= REQ_SORTED;
                q->nr_sorted++;
                if (rq_mergeable(rq)) {
@@ -692,7 +701,7 @@ void __elv_add_request(struct request_queue *q, struct request *rq, int where,
                 * this request is scheduling boundary, update
                 * end_sector
                 */
-               if (blk_fs_request(rq)) {
+               if (blk_fs_request(rq) || blk_discard_rq(rq)) {
                        q->end_sector = rq_end_sector(rq);
                        q->boundary_rq = rq;
                }
@@ -745,7 +754,7 @@ struct request *elv_next_request(struct request_queue *q)
                 * not ever see it.
                 */
                if (blk_empty_barrier(rq)) {
-                       end_queued_request(rq, 1);
+                       __blk_end_request(rq, 0, blk_rq_bytes(rq));
                        continue;
                }
                if (!(rq->cmd_flags & REQ_STARTED)) {
@@ -764,6 +773,12 @@ struct request *elv_next_request(struct request_queue *q)
                         */
                        rq->cmd_flags |= REQ_STARTED;
                        blk_add_trace_rq(q, rq, BLK_TA_ISSUE);
+
+                       /*
+                        * We are now handing the request to the hardware,
+                        * add the timeout handler
+                        */
+                       blk_add_timer(rq);
                }
 
                if (!q->boundary_rq || q->boundary_rq == rq) {
@@ -782,7 +797,6 @@ struct request *elv_next_request(struct request_queue *q)
                         * device can handle
                         */
                        rq->nr_phys_segments++;
-                       rq->nr_hw_segments++;
                }
 
                if (!q->prep_rq_fn)
@@ -805,14 +819,13 @@ struct request *elv_next_request(struct request_queue *q)
                                 * so that we don't add it again
                                 */
                                --rq->nr_phys_segments;
-                               --rq->nr_hw_segments;
                        }
 
                        rq = NULL;
                        break;
                } else if (ret == BLKPREP_KILL) {
                        rq->cmd_flags |= REQ_QUIET;
-                       end_queued_request(rq, 0);
+                       __blk_end_request(rq, -EIO, blk_rq_bytes(rq));
                } else {
                        printk(KERN_ERR "%s: bad return=%d\n", __func__, ret);
                        break;
@@ -901,6 +914,19 @@ int elv_may_queue(struct request_queue *q, int rw)
        return ELV_MQUEUE_MAY;
 }
 
+void elv_abort_queue(struct request_queue *q)
+{
+       struct request *rq;
+
+       while (!list_empty(&q->queue_head)) {
+               rq = list_entry_rq(q->queue_head.next);
+               rq->cmd_flags |= REQ_QUIET;
+               blk_add_trace_rq(q, rq, BLK_TA_ABORT);
+               __blk_end_request(rq, -EIO, blk_rq_bytes(rq));
+       }
+}
+EXPORT_SYMBOL(elv_abort_queue);
+
 void elv_completed_request(struct request_queue *q, struct request *rq)
 {
        elevator_t *e = q->elevator;
index e0ce23ac2ece84b24a283f9ae9203ec3291f2f78..4cd3433c99ac7d64fe05b72a1061cba01059920a 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/kobj_map.h>
 #include <linux/buffer_head.h>
 #include <linux/mutex.h>
+#include <linux/idr.h>
 
 #include "blk.h"
 
@@ -24,8 +25,194 @@ static DEFINE_MUTEX(block_class_lock);
 struct kobject *block_depr;
 #endif
 
+/* for extended dynamic devt allocation, currently only one major is used */
+#define MAX_EXT_DEVT           (1 << MINORBITS)
+
+/* For extended devt allocation.  ext_devt_mutex prevents look up
+ * results from going away underneath its user.
+ */
+static DEFINE_MUTEX(ext_devt_mutex);
+static DEFINE_IDR(ext_devt_idr);
+
 static struct device_type disk_type;
 
+/**
+ * disk_get_part - get partition
+ * @disk: disk to look partition from
+ * @partno: partition number
+ *
+ * Look for partition @partno from @disk.  If found, increment
+ * reference count and return it.
+ *
+ * CONTEXT:
+ * Don't care.
+ *
+ * RETURNS:
+ * Pointer to the found partition on success, NULL if not found.
+ */
+struct hd_struct *disk_get_part(struct gendisk *disk, int partno)
+{
+       struct hd_struct *part = NULL;
+       struct disk_part_tbl *ptbl;
+
+       if (unlikely(partno < 0))
+               return NULL;
+
+       rcu_read_lock();
+
+       ptbl = rcu_dereference(disk->part_tbl);
+       if (likely(partno < ptbl->len)) {
+               part = rcu_dereference(ptbl->part[partno]);
+               if (part)
+                       get_device(part_to_dev(part));
+       }
+
+       rcu_read_unlock();
+
+       return part;
+}
+EXPORT_SYMBOL_GPL(disk_get_part);
+
+/**
+ * disk_part_iter_init - initialize partition iterator
+ * @piter: iterator to initialize
+ * @disk: disk to iterate over
+ * @flags: DISK_PITER_* flags
+ *
+ * Initialize @piter so that it iterates over partitions of @disk.
+ *
+ * CONTEXT:
+ * Don't care.
+ */
+void disk_part_iter_init(struct disk_part_iter *piter, struct gendisk *disk,
+                         unsigned int flags)
+{
+       struct disk_part_tbl *ptbl;
+
+       rcu_read_lock();
+       ptbl = rcu_dereference(disk->part_tbl);
+
+       piter->disk = disk;
+       piter->part = NULL;
+
+       if (flags & DISK_PITER_REVERSE)
+               piter->idx = ptbl->len - 1;
+       else if (flags & DISK_PITER_INCL_PART0)
+               piter->idx = 0;
+       else
+               piter->idx = 1;
+
+       piter->flags = flags;
+
+       rcu_read_unlock();
+}
+EXPORT_SYMBOL_GPL(disk_part_iter_init);
+
+/**
+ * disk_part_iter_next - proceed iterator to the next partition and return it
+ * @piter: iterator of interest
+ *
+ * Proceed @piter to the next partition and return it.
+ *
+ * CONTEXT:
+ * Don't care.
+ */
+struct hd_struct *disk_part_iter_next(struct disk_part_iter *piter)
+{
+       struct disk_part_tbl *ptbl;
+       int inc, end;
+
+       /* put the last partition */
+       disk_put_part(piter->part);
+       piter->part = NULL;
+
+       /* get part_tbl */
+       rcu_read_lock();
+       ptbl = rcu_dereference(piter->disk->part_tbl);
+
+       /* determine iteration parameters */
+       if (piter->flags & DISK_PITER_REVERSE) {
+               inc = -1;
+               if (piter->flags & DISK_PITER_INCL_PART0)
+                       end = -1;
+               else
+                       end = 0;
+       } else {
+               inc = 1;
+               end = ptbl->len;
+       }
+
+       /* iterate to the next partition */
+       for (; piter->idx != end; piter->idx += inc) {
+               struct hd_struct *part;
+
+               part = rcu_dereference(ptbl->part[piter->idx]);
+               if (!part)
+                       continue;
+               if (!(piter->flags & DISK_PITER_INCL_EMPTY) && !part->nr_sects)
+                       continue;
+
+               get_device(part_to_dev(part));
+               piter->part = part;
+               piter->idx += inc;
+               break;
+       }
+
+       rcu_read_unlock();
+
+       return piter->part;
+}
+EXPORT_SYMBOL_GPL(disk_part_iter_next);
+
+/**
+ * disk_part_iter_exit - finish up partition iteration
+ * @piter: iter of interest
+ *
+ * Called when iteration is over.  Cleans up @piter.
+ *
+ * CONTEXT:
+ * Don't care.
+ */
+void disk_part_iter_exit(struct disk_part_iter *piter)
+{
+       disk_put_part(piter->part);
+       piter->part = NULL;
+}
+EXPORT_SYMBOL_GPL(disk_part_iter_exit);
+
+/**
+ * disk_map_sector_rcu - map sector to partition
+ * @disk: gendisk of interest
+ * @sector: sector to map
+ *
+ * Find out which partition @sector maps to on @disk.  This is
+ * primarily used for stats accounting.
+ *
+ * CONTEXT:
+ * RCU read locked.  The returned partition pointer is valid only
+ * while preemption is disabled.
+ *
+ * RETURNS:
+ * Found partition on success, part0 is returned if no partition matches
+ */
+struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, sector_t sector)
+{
+       struct disk_part_tbl *ptbl;
+       int i;
+
+       ptbl = rcu_dereference(disk->part_tbl);
+
+       for (i = 1; i < ptbl->len; i++) {
+               struct hd_struct *part = rcu_dereference(ptbl->part[i]);
+
+               if (part && part->start_sect <= sector &&
+                   sector < part->start_sect + part->nr_sects)
+                       return part;
+       }
+       return &disk->part0;
+}
+EXPORT_SYMBOL_GPL(disk_map_sector_rcu);
+
 /*
  * Can be deleted altogether. Later.
  *
@@ -43,14 +230,14 @@ static inline int major_to_index(int major)
 }
 
 #ifdef CONFIG_PROC_FS
-void blkdev_show(struct seq_file *f, off_t offset)
+void blkdev_show(struct seq_file *seqf, off_t offset)
 {
        struct blk_major_name *dp;
 
        if (offset < BLKDEV_MAJOR_HASH_SIZE) {
                mutex_lock(&block_class_lock);
                for (dp = major_names[offset]; dp; dp = dp->next)
-                       seq_printf(f, "%3d %s\n", dp->major, dp->name);
+                       seq_printf(seqf, "%3d %s\n", dp->major, dp->name);
                mutex_unlock(&block_class_lock);
        }
 }
@@ -136,6 +323,118 @@ EXPORT_SYMBOL(unregister_blkdev);
 
 static struct kobj_map *bdev_map;
 
+/**
+ * blk_mangle_minor - scatter minor numbers apart
+ * @minor: minor number to mangle
+ *
+ * Scatter consecutively allocated @minor number apart if MANGLE_DEVT
+ * is enabled.  Mangling twice gives the original value.
+ *
+ * RETURNS:
+ * Mangled value.
+ *
+ * CONTEXT:
+ * Don't care.
+ */
+static int blk_mangle_minor(int minor)
+{
+#ifdef CONFIG_DEBUG_BLOCK_EXT_DEVT
+       int i;
+
+       for (i = 0; i < MINORBITS / 2; i++) {
+               int low = minor & (1 << i);
+               int high = minor & (1 << (MINORBITS - 1 - i));
+               int distance = MINORBITS - 1 - 2 * i;
+
+               minor ^= low | high;    /* clear both bits */
+               low <<= distance;       /* swap the positions */
+               high >>= distance;
+               minor |= low | high;    /* and set */
+       }
+#endif
+       return minor;
+}
+
+/**
+ * blk_alloc_devt - allocate a dev_t for a partition
+ * @part: partition to allocate dev_t for
+ * @gfp_mask: memory allocation flag
+ * @devt: out parameter for resulting dev_t
+ *
+ * Allocate a dev_t for block device.
+ *
+ * RETURNS:
+ * 0 on success, allocated dev_t is returned in *@devt.  -errno on
+ * failure.
+ *
+ * CONTEXT:
+ * Might sleep.
+ */
+int blk_alloc_devt(struct hd_struct *part, dev_t *devt)
+{
+       struct gendisk *disk = part_to_disk(part);
+       int idx, rc;
+
+       /* in consecutive minor range? */
+       if (part->partno < disk->minors) {
+               *devt = MKDEV(disk->major, disk->first_minor + part->partno);
+               return 0;
+       }
+
+       /* allocate ext devt */
+       do {
+               if (!idr_pre_get(&ext_devt_idr, GFP_KERNEL))
+                       return -ENOMEM;
+               rc = idr_get_new(&ext_devt_idr, part, &idx);
+       } while (rc == -EAGAIN);
+
+       if (rc)
+               return rc;
+
+       if (idx > MAX_EXT_DEVT) {
+               idr_remove(&ext_devt_idr, idx);
+               return -EBUSY;
+       }
+
+       *devt = MKDEV(BLOCK_EXT_MAJOR, blk_mangle_minor(idx));
+       return 0;
+}
+
+/**
+ * blk_free_devt - free a dev_t
+ * @devt: dev_t to free
+ *
+ * Free @devt which was allocated using blk_alloc_devt().
+ *
+ * CONTEXT:
+ * Might sleep.
+ */
+void blk_free_devt(dev_t devt)
+{
+       might_sleep();
+
+       if (devt == MKDEV(0, 0))
+               return;
+
+       if (MAJOR(devt) == BLOCK_EXT_MAJOR) {
+               mutex_lock(&ext_devt_mutex);
+               idr_remove(&ext_devt_idr, blk_mangle_minor(MINOR(devt)));
+               mutex_unlock(&ext_devt_mutex);
+       }
+}
+
+static char *bdevt_str(dev_t devt, char *buf)
+{
+       if (MAJOR(devt) <= 0xff && MINOR(devt) <= 0xff) {
+               char tbuf[BDEVT_SIZE];
+               snprintf(tbuf, BDEVT_SIZE, "%02x%02x", MAJOR(devt), MINOR(devt));
+               snprintf(buf, BDEVT_SIZE, "%-9s", tbuf);
+       } else
+               snprintf(buf, BDEVT_SIZE, "%03x:%05x", MAJOR(devt), MINOR(devt));
+
+       return buf;
+}
+
 /*
  * Register device numbers dev..(dev+range-1)
  * range must be nonzero
@@ -157,11 +456,11 @@ void blk_unregister_region(dev_t devt, unsigned long range)
 
 EXPORT_SYMBOL(blk_unregister_region);
 
-static struct kobject *exact_match(dev_t devt, int *part, void *data)
+static struct kobject *exact_match(dev_t devt, int *partno, void *data)
 {
        struct gendisk *p = data;
 
-       return &p->dev.kobj;
+       return &disk_to_dev(p)->kobj;
 }
 
 static int exact_lock(dev_t devt, void *data)
@@ -179,21 +478,46 @@ static int exact_lock(dev_t devt, void *data)
  *
  * This function registers the partitioning information in @disk
  * with the kernel.
+ *
+ * FIXME: error handling
  */
 void add_disk(struct gendisk *disk)
 {
        struct backing_dev_info *bdi;
+       dev_t devt;
        int retval;
 
+       /* minors == 0 indicates to use ext devt from part0 and should
+        * be accompanied with EXT_DEVT flag.  Make sure all
+        * parameters make sense.
+        */
+       WARN_ON(disk->minors && !(disk->major || disk->first_minor));
+       WARN_ON(!disk->minors && !(disk->flags & GENHD_FL_EXT_DEVT));
+
        disk->flags |= GENHD_FL_UP;
-       blk_register_region(MKDEV(disk->major, disk->first_minor),
-                           disk->minors, NULL, exact_match, exact_lock, disk);
+
+       retval = blk_alloc_devt(&disk->part0, &devt);
+       if (retval) {
+               WARN_ON(1);
+               return;
+       }
+       disk_to_dev(disk)->devt = devt;
+
+       /* ->major and ->first_minor aren't supposed to be
+        * dereferenced from here on, but set them just in case.
+        */
+       disk->major = MAJOR(devt);
+       disk->first_minor = MINOR(devt);
+
+       blk_register_region(disk_devt(disk), disk->minors, NULL,
+                           exact_match, exact_lock, disk);
        register_disk(disk);
        blk_register_queue(disk);
 
        bdi = &disk->queue->backing_dev_info;
-       bdi_register_dev(bdi, MKDEV(disk->major, disk->first_minor));
-       retval = sysfs_create_link(&disk->dev.kobj, &bdi->dev->kobj, "bdi");
+       bdi_register_dev(bdi, disk_devt(disk));
+       retval = sysfs_create_link(&disk_to_dev(disk)->kobj, &bdi->dev->kobj,
+                                  "bdi");
        WARN_ON(retval);
 }
 
@@ -202,78 +526,71 @@ EXPORT_SYMBOL(del_gendisk);       /* in partitions/check.c */
 
 void unlink_gendisk(struct gendisk *disk)
 {
-       sysfs_remove_link(&disk->dev.kobj, "bdi");
+       sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi");
        bdi_unregister(&disk->queue->backing_dev_info);
        blk_unregister_queue(disk);
-       blk_unregister_region(MKDEV(disk->major, disk->first_minor),
-                             disk->minors);
+       blk_unregister_region(disk_devt(disk), disk->minors);
 }
 
 /**
  * get_gendisk - get partitioning information for a given device
- * @dev: device to get partitioning information for
+ * @devt: device to get partitioning information for
+ * @part: returned partition index
  *
  * This function gets the structure containing partitioning
- * information for the given device @dev.
+ * information for the given device @devt.
  */
-struct gendisk *get_gendisk(dev_t devt, int *part)
+struct gendisk *get_gendisk(dev_t devt, int *partno)
 {
-       struct kobject *kobj = kobj_lookup(bdev_map, devt, part);
-       struct device *dev = kobj_to_dev(kobj);
+       struct gendisk *disk = NULL;
+
+       if (MAJOR(devt) != BLOCK_EXT_MAJOR) {
+               struct kobject *kobj;
+
+               kobj = kobj_lookup(bdev_map, devt, partno);
+               if (kobj)
+                       disk = dev_to_disk(kobj_to_dev(kobj));
+       } else {
+               struct hd_struct *part;
 
-       return  kobj ? dev_to_disk(dev) : NULL;
+               mutex_lock(&ext_devt_mutex);
+               part = idr_find(&ext_devt_idr, blk_mangle_minor(MINOR(devt)));
+               if (part && get_disk(part_to_disk(part))) {
+                       *partno = part->partno;
+                       disk = part_to_disk(part);
+               }
+               mutex_unlock(&ext_devt_mutex);
+       }
+
+       return disk;
 }
 
-/*
- * print a partitions - intended for places where the root filesystem can't be
- * mounted and thus to give the victim some idea of what went wrong
+/**
+ * bdget_disk - do bdget() by gendisk and partition number
+ * @disk: gendisk of interest
+ * @partno: partition number
+ *
+ * Find partition @partno from @disk, do bdget() on it.
+ *
+ * CONTEXT:
+ * Don't care.
+ *
+ * RETURNS:
+ * Resulting block_device on success, NULL on failure.
  */
-static int printk_partition(struct device *dev, void *data)
+struct block_device *bdget_disk(struct gendisk *disk, int partno)
 {
-       struct gendisk *sgp;
-       char buf[BDEVNAME_SIZE];
-       int n;
-
-       if (dev->type != &disk_type)
-               goto exit;
+       struct hd_struct *part;
+       struct block_device *bdev = NULL;
 
-       sgp = dev_to_disk(dev);
-       /*
-        * Don't show empty devices or things that have been surpressed
-        */
-       if (get_capacity(sgp) == 0 ||
-           (sgp->flags & GENHD_FL_SUPPRESS_PARTITION_INFO))
-               goto exit;
+       part = disk_get_part(disk, partno);
+       if (part)
+               bdev = bdget(part_devt(part));
+       disk_put_part(part);
 
-       /*
-        * Note, unlike /proc/partitions, I am showing the numbers in
-        * hex - the same format as the root= option takes.
-        */
-       printk("%02x%02x %10llu %s",
-               sgp->major, sgp->first_minor,
-               (unsigned long long)get_capacity(sgp) >> 1,
-               disk_name(sgp, 0, buf));
-       if (sgp->driverfs_dev != NULL &&
-           sgp->driverfs_dev->driver != NULL)
-               printk(" driver: %s\n",
-                       sgp->driverfs_dev->driver->name);
-       else
-               printk(" (driver?)\n");
-
-       /* now show the partitions */
-       for (n = 0; n < sgp->minors - 1; ++n) {
-               if (sgp->part[n] == NULL)
-                       goto exit;
-               if (sgp->part[n]->nr_sects == 0)
-                       goto exit;
-               printk("  %02x%02x %10llu %s\n",
-                       sgp->major, n + 1 + sgp->first_minor,
-                       (unsigned long long)sgp->part[n]->nr_sects >> 1,
-                       disk_name(sgp, n + 1, buf));
-       }
-exit:
-       return 0;
+       return bdev;
 }
+EXPORT_SYMBOL(bdget_disk);
 
 /*
  * print a full list of all partitions - intended for places where the root
@@ -282,120 +599,145 @@ exit:
  */
 void __init printk_all_partitions(void)
 {
-       mutex_lock(&block_class_lock);
-       class_for_each_device(&block_class, NULL, NULL, printk_partition);
-       mutex_unlock(&block_class_lock);
+       struct class_dev_iter iter;
+       struct device *dev;
+
+       class_dev_iter_init(&iter, &block_class, NULL, &disk_type);
+       while ((dev = class_dev_iter_next(&iter))) {
+               struct gendisk *disk = dev_to_disk(dev);
+               struct disk_part_iter piter;
+               struct hd_struct *part;
+               char name_buf[BDEVNAME_SIZE];
+               char devt_buf[BDEVT_SIZE];
+
+               /*
+                * Don't show empty devices or things that have been
+                * surpressed
+                */
+               if (get_capacity(disk) == 0 ||
+                   (disk->flags & GENHD_FL_SUPPRESS_PARTITION_INFO))
+                       continue;
+
+               /*
+                * Note, unlike /proc/partitions, I am showing the
+                * numbers in hex - the same format as the root=
+                * option takes.
+                */
+               disk_part_iter_init(&piter, disk, DISK_PITER_INCL_PART0);
+               while ((part = disk_part_iter_next(&piter))) {
+                       bool is_part0 = part == &disk->part0;
+
+                       printk("%s%s %10llu %s", is_part0 ? "" : "  ",
+                              bdevt_str(part_devt(part), devt_buf),
+                              (unsigned long long)part->nr_sects >> 1,
+                              disk_name(disk, part->partno, name_buf));
+                       if (is_part0) {
+                               if (disk->driverfs_dev != NULL &&
+                                   disk->driverfs_dev->driver != NULL)
+                                       printk(" driver: %s\n",
+                                             disk->driverfs_dev->driver->name);
+                               else
+                                       printk(" (driver?)\n");
+                       } else
+                               printk("\n");
+               }
+               disk_part_iter_exit(&piter);
+       }
+       class_dev_iter_exit(&iter);
 }
 
 #ifdef CONFIG_PROC_FS
 /* iterator */
-static int find_start(struct device *dev, void *data)
+static void *disk_seqf_start(struct seq_file *seqf, loff_t *pos)
 {
-       loff_t *k = data;
+       loff_t skip = *pos;
+       struct class_dev_iter *iter;
+       struct device *dev;
 
-       if (dev->type != &disk_type)
-               return 0;
-       if (!*k)
-               return 1;
-       (*k)--;
-       return 0;
+       iter = kmalloc(sizeof(*iter), GFP_KERNEL);
+       if (!iter)
+               return ERR_PTR(-ENOMEM);
+
+       seqf->private = iter;
+       class_dev_iter_init(iter, &block_class, NULL, &disk_type);
+       do {
+               dev = class_dev_iter_next(iter);
+               if (!dev)
+                       return NULL;
+       } while (skip--);
+
+       return dev_to_disk(dev);
 }
 
-static void *part_start(struct seq_file *part, loff_t *pos)
+static void *disk_seqf_next(struct seq_file *seqf, void *v, loff_t *pos)
 {
        struct device *dev;
-       loff_t k = *pos;
-
-       if (!k)
-               part->private = (void *)1LU;    /* tell show to print header */
 
-       mutex_lock(&block_class_lock);
-       dev = class_find_device(&block_class, NULL, &k, find_start);
-       if (dev) {
-               put_device(dev);
+       (*pos)++;
+       dev = class_dev_iter_next(seqf->private);
+       if (dev)
                return dev_to_disk(dev);
-       }
+
        return NULL;
 }
 
-static int find_next(struct device *dev, void *data)
+static void disk_seqf_stop(struct seq_file *seqf, void *v)
 {
-       if (dev->type == &disk_type)
-               return 1;
-       return 0;
-}
+       struct class_dev_iter *iter = seqf->private;
 
-static void *part_next(struct seq_file *part, void *v, loff_t *pos)
-{
-       struct gendisk *gp = v;
-       struct device *dev;
-       ++*pos;
-       dev = class_find_device(&block_class, &gp->dev, NULL, find_next);
-       if (dev) {
-               put_device(dev);
-               return dev_to_disk(dev);
+       /* stop is called even after start failed :-( */
+       if (iter) {
+               class_dev_iter_exit(iter);
+               kfree(iter);
        }
-       return NULL;
 }
 
-static void part_stop(struct seq_file *part, void *v)
+static void *show_partition_start(struct seq_file *seqf, loff_t *pos)
 {
-       mutex_unlock(&block_class_lock);
+       static void *p;
+
+       p = disk_seqf_start(seqf, pos);
+       if (!IS_ERR(p) && p && !*pos)
+               seq_puts(seqf, "major minor  #blocks  name\n\n");
+       return p;
 }
 
-static int show_partition(struct seq_file *part, void *v)
+static int show_partition(struct seq_file *seqf, void *v)
 {
        struct gendisk *sgp = v;
-       int n;
+       struct disk_part_iter piter;
+       struct hd_struct *part;
        char buf[BDEVNAME_SIZE];
 
-       /*
-        * Print header if start told us to do.  This is to preserve
-        * the original behavior of not printing header if no
-        * partition exists.  This hackery will be removed later with
-        * class iteration clean up.
-        */
-       if (part->private) {
-               seq_puts(part, "major minor  #blocks  name\n\n");
-               part->private = NULL;
-       }
-
        /* Don't show non-partitionable removeable devices or empty devices */
-       if (!get_capacity(sgp) ||
-                       (sgp->minors == 1 && (sgp->flags & GENHD_FL_REMOVABLE)))
+       if (!get_capacity(sgp) || (!disk_partitionable(sgp) &&
+                                  (sgp->flags & GENHD_FL_REMOVABLE)))
                return 0;
        if (sgp->flags & GENHD_FL_SUPPRESS_PARTITION_INFO)
                return 0;
 
        /* show the full disk and all non-0 size partitions of it */
-       seq_printf(part, "%4d  %4d %10llu %s\n",
-               sgp->major, sgp->first_minor,
-               (unsigned long long)get_capacity(sgp) >> 1,
-               disk_name(sgp, 0, buf));
-       for (n = 0; n < sgp->minors - 1; n++) {
-               if (!sgp->part[n])
-                       continue;
-               if (sgp->part[n]->nr_sects == 0)
-                       continue;
-               seq_printf(part, "%4d  %4d %10llu %s\n",
-                       sgp->major, n + 1 + sgp->first_minor,
-                       (unsigned long long)sgp->part[n]->nr_sects >> 1 ,
-                       disk_name(sgp, n + 1, buf));
-       }
+       disk_part_iter_init(&piter, sgp, DISK_PITER_INCL_PART0);
+       while ((part = disk_part_iter_next(&piter)))
+               seq_printf(seqf, "%4d  %7d %10llu %s\n",
+                          MAJOR(part_devt(part)), MINOR(part_devt(part)),
+                          (unsigned long long)part->nr_sects >> 1,
+                          disk_name(sgp, part->partno, buf));
+       disk_part_iter_exit(&piter);
 
        return 0;
 }
 
 const struct seq_operations partitions_op = {
-       .start  = part_start,
-       .next   = part_next,
-       .stop   = part_stop,
+       .start  = show_partition_start,
+       .next   = disk_seqf_next,
+       .stop   = disk_seqf_stop,
        .show   = show_partition
 };
 #endif
 
 
-static struct kobject *base_probe(dev_t devt, int *part, void *data)
+static struct kobject *base_probe(dev_t devt, int *partno, void *data)
 {
        if (request_module("block-major-%d-%d", MAJOR(devt), MINOR(devt)) > 0)
                /* Make old-style 2.4 aliases work */
@@ -431,29 +773,29 @@ static ssize_t disk_range_show(struct device *dev,
        return sprintf(buf, "%d\n", disk->minors);
 }
 
-static ssize_t disk_removable_show(struct device *dev,
+static ssize_t disk_ext_range_show(struct device *dev,
                                   struct device_attribute *attr, char *buf)
 {
        struct gendisk *disk = dev_to_disk(dev);
 
-       return sprintf(buf, "%d\n",
-                      (disk->flags & GENHD_FL_REMOVABLE ? 1 : 0));
+       return sprintf(buf, "%d\n", disk_max_parts(disk));
 }
 
-static ssize_t disk_ro_show(struct device *dev,
+static ssize_t disk_removable_show(struct device *dev,
                                   struct device_attribute *attr, char *buf)
 {
        struct gendisk *disk = dev_to_disk(dev);
 
-       return sprintf(buf, "%d\n", disk->policy ? 1 : 0);
+       return sprintf(buf, "%d\n",
+                      (disk->flags & GENHD_FL_REMOVABLE ? 1 : 0));
 }
 
-static ssize_t disk_size_show(struct device *dev,
-                             struct device_attribute *attr, char *buf)
+static ssize_t disk_ro_show(struct device *dev,
+                                  struct device_attribute *attr, char *buf)
 {
        struct gendisk *disk = dev_to_disk(dev);
 
-       return sprintf(buf, "%llu\n", (unsigned long long)get_capacity(disk));
+       return sprintf(buf, "%d\n", get_disk_ro(disk) ? 1 : 0);
 }
 
 static ssize_t disk_capability_show(struct device *dev,
@@ -464,73 +806,26 @@ static ssize_t disk_capability_show(struct device *dev,
        return sprintf(buf, "%x\n", disk->flags);
 }
 
-static ssize_t disk_stat_show(struct device *dev,
-                             struct device_attribute *attr, char *buf)
-{
-       struct gendisk *disk = dev_to_disk(dev);
-
-       preempt_disable();
-       disk_round_stats(disk);
-       preempt_enable();
-       return sprintf(buf,
-               "%8lu %8lu %8llu %8u "
-               "%8lu %8lu %8llu %8u "
-               "%8u %8u %8u"
-               "\n",
-               disk_stat_read(disk, ios[READ]),
-               disk_stat_read(disk, merges[READ]),
-               (unsigned long long)disk_stat_read(disk, sectors[READ]),
-               jiffies_to_msecs(disk_stat_read(disk, ticks[READ])),
-               disk_stat_read(disk, ios[WRITE]),
-               disk_stat_read(disk, merges[WRITE]),
-               (unsigned long long)disk_stat_read(disk, sectors[WRITE]),
-               jiffies_to_msecs(disk_stat_read(disk, ticks[WRITE])),
-               disk->in_flight,
-               jiffies_to_msecs(disk_stat_read(disk, io_ticks)),
-               jiffies_to_msecs(disk_stat_read(disk, time_in_queue)));
-}
-
-#ifdef CONFIG_FAIL_MAKE_REQUEST
-static ssize_t disk_fail_show(struct device *dev,
-                             struct device_attribute *attr, char *buf)
-{
-       struct gendisk *disk = dev_to_disk(dev);
-
-       return sprintf(buf, "%d\n", disk->flags & GENHD_FL_FAIL ? 1 : 0);
-}
-
-static ssize_t disk_fail_store(struct device *dev,
-                              struct device_attribute *attr,
-                              const char *buf, size_t count)
-{
-       struct gendisk *disk = dev_to_disk(dev);
-       int i;
-
-       if (count > 0 && sscanf(buf, "%d", &i) > 0) {
-               if (i == 0)
-                       disk->flags &= ~GENHD_FL_FAIL;
-               else
-                       disk->flags |= GENHD_FL_FAIL;
-       }
-
-       return count;
-}
-
-#endif
-
 static DEVICE_ATTR(range, S_IRUGO, disk_range_show, NULL);
+static DEVICE_ATTR(ext_range, S_IRUGO, disk_ext_range_show, NULL);
 static DEVICE_ATTR(removable, S_IRUGO, disk_removable_show, NULL);
 static DEVICE_ATTR(ro, S_IRUGO, disk_ro_show, NULL);
-static DEVICE_ATTR(size, S_IRUGO, disk_size_show, NULL);
+static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL);
 static DEVICE_ATTR(capability, S_IRUGO, disk_capability_show, NULL);
-static DEVICE_ATTR(stat, S_IRUGO, disk_stat_show, NULL);
+static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL);
 #ifdef CONFIG_FAIL_MAKE_REQUEST
 static struct device_attribute dev_attr_fail =
-       __ATTR(make-it-fail, S_IRUGO|S_IWUSR, disk_fail_show, disk_fail_store);
+       __ATTR(make-it-fail, S_IRUGO|S_IWUSR, part_fail_show, part_fail_store);
+#endif
+#ifdef CONFIG_FAIL_IO_TIMEOUT
+static struct device_attribute dev_attr_fail_timeout =
+       __ATTR(io-timeout-fail,  S_IRUGO|S_IWUSR, part_timeout_show,
+               part_timeout_store);
 #endif
 
 static struct attribute *disk_attrs[] = {
        &dev_attr_range.attr,
+       &dev_attr_ext_range.attr,
        &dev_attr_removable.attr,
        &dev_attr_ro.attr,
        &dev_attr_size.attr,
@@ -538,6 +833,9 @@ static struct attribute *disk_attrs[] = {
        &dev_attr_stat.attr,
 #ifdef CONFIG_FAIL_MAKE_REQUEST
        &dev_attr_fail.attr,
+#endif
+#ifdef CONFIG_FAIL_IO_TIMEOUT
+       &dev_attr_fail_timeout.attr,
 #endif
        NULL
 };
@@ -551,13 +849,87 @@ static struct attribute_group *disk_attr_groups[] = {
        NULL
 };
 
+static void disk_free_ptbl_rcu_cb(struct rcu_head *head)
+{
+       struct disk_part_tbl *ptbl =
+               container_of(head, struct disk_part_tbl, rcu_head);
+
+       kfree(ptbl);
+}
+
+/**
+ * disk_replace_part_tbl - replace disk->part_tbl in RCU-safe way
+ * @disk: disk to replace part_tbl for
+ * @new_ptbl: new part_tbl to install
+ *
+ * Replace disk->part_tbl with @new_ptbl in RCU-safe way.  The
+ * original ptbl is freed using RCU callback.
+ *
+ * LOCKING:
+ * Matching bd_mutx locked.
+ */
+static void disk_replace_part_tbl(struct gendisk *disk,
+                                 struct disk_part_tbl *new_ptbl)
+{
+       struct disk_part_tbl *old_ptbl = disk->part_tbl;
+
+       rcu_assign_pointer(disk->part_tbl, new_ptbl);
+       if (old_ptbl)
+               call_rcu(&old_ptbl->rcu_head, disk_free_ptbl_rcu_cb);
+}
+
+/**
+ * disk_expand_part_tbl - expand disk->part_tbl
+ * @disk: disk to expand part_tbl for
+ * @partno: expand such that this partno can fit in
+ *
+ * Expand disk->part_tbl such that @partno can fit in.  disk->part_tbl
+ * uses RCU to allow unlocked dereferencing for stats and other stuff.
+ *
+ * LOCKING:
+ * Matching bd_mutex locked, might sleep.
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
+ */
+int disk_expand_part_tbl(struct gendisk *disk, int partno)
+{
+       struct disk_part_tbl *old_ptbl = disk->part_tbl;
+       struct disk_part_tbl *new_ptbl;
+       int len = old_ptbl ? old_ptbl->len : 0;
+       int target = partno + 1;
+       size_t size;
+       int i;
+
+       /* disk_max_parts() is zero during initialization, ignore if so */
+       if (disk_max_parts(disk) && target > disk_max_parts(disk))
+               return -EINVAL;
+
+       if (target <= len)
+               return 0;
+
+       size = sizeof(*new_ptbl) + target * sizeof(new_ptbl->part[0]);
+       new_ptbl = kzalloc_node(size, GFP_KERNEL, disk->node_id);
+       if (!new_ptbl)
+               return -ENOMEM;
+
+       INIT_RCU_HEAD(&new_ptbl->rcu_head);
+       new_ptbl->len = target;
+
+       for (i = 0; i < len; i++)
+               rcu_assign_pointer(new_ptbl->part[i], old_ptbl->part[i]);
+
+       disk_replace_part_tbl(disk, new_ptbl);
+       return 0;
+}
+
 static void disk_release(struct device *dev)
 {
        struct gendisk *disk = dev_to_disk(dev);
 
        kfree(disk->random);
-       kfree(disk->part);
-       free_disk_stats(disk);
+       disk_replace_part_tbl(disk, NULL);
+       free_part_stats(&disk->part0);
        kfree(disk);
 }
 struct class block_class = {
@@ -578,83 +950,31 @@ static struct device_type disk_type = {
  * The output looks suspiciously like /proc/partitions with a bunch of
  * extra fields.
  */
-
-static void *diskstats_start(struct seq_file *part, loff_t *pos)
-{
-       struct device *dev;
-       loff_t k = *pos;
-
-       mutex_lock(&block_class_lock);
-       dev = class_find_device(&block_class, NULL, &k, find_start);
-       if (dev) {
-               put_device(dev);
-               return dev_to_disk(dev);
-       }
-       return NULL;
-}
-
-static void *diskstats_next(struct seq_file *part, void *v, loff_t *pos)
-{
-       struct gendisk *gp = v;
-       struct device *dev;
-
-       ++*pos;
-       dev = class_find_device(&block_class, &gp->dev, NULL, find_next);
-       if (dev) {
-               put_device(dev);
-               return dev_to_disk(dev);
-       }
-       return NULL;
-}
-
-static void diskstats_stop(struct seq_file *part, void *v)
-{
-       mutex_unlock(&block_class_lock);
-}
-
-static int diskstats_show(struct seq_file *s, void *v)
+static int diskstats_show(struct seq_file *seqf, void *v)
 {
        struct gendisk *gp = v;
+       struct disk_part_iter piter;
+       struct hd_struct *hd;
        char buf[BDEVNAME_SIZE];
-       int n = 0;
+       int cpu;
 
        /*
-       if (&gp->dev.kobj.entry == block_class.devices.next)
-               seq_puts(s,     "major minor name"
+       if (&disk_to_dev(gp)->kobj.entry == block_class.devices.next)
+               seq_puts(seqf,  "major minor name"
                                "     rio rmerge rsect ruse wio wmerge "
                                "wsect wuse running use aveq"
                                "\n\n");
        */
  
-       preempt_disable();
-       disk_round_stats(gp);
-       preempt_enable();
-       seq_printf(s, "%4d %4d %s %lu %lu %llu %u %lu %lu %llu %u %u %u %u\n",
-               gp->major, n + gp->first_minor, disk_name(gp, n, buf),
-               disk_stat_read(gp, ios[0]), disk_stat_read(gp, merges[0]),
-               (unsigned long long)disk_stat_read(gp, sectors[0]),
-               jiffies_to_msecs(disk_stat_read(gp, ticks[0])),
-               disk_stat_read(gp, ios[1]), disk_stat_read(gp, merges[1]),
-               (unsigned long long)disk_stat_read(gp, sectors[1]),
-               jiffies_to_msecs(disk_stat_read(gp, ticks[1])),
-               gp->in_flight,
-               jiffies_to_msecs(disk_stat_read(gp, io_ticks)),
-               jiffies_to_msecs(disk_stat_read(gp, time_in_queue)));
-
-       /* now show all non-0 size partitions of it */
-       for (n = 0; n < gp->minors - 1; n++) {
-               struct hd_struct *hd = gp->part[n];
-
-               if (!hd || !hd->nr_sects)
-                       continue;
-
-               preempt_disable();
-               part_round_stats(hd);
-               preempt_enable();
-               seq_printf(s, "%4d %4d %s %lu %lu %llu "
+       disk_part_iter_init(&piter, gp, DISK_PITER_INCL_PART0);
+       while ((hd = disk_part_iter_next(&piter))) {
+               cpu = part_stat_lock();
+               part_round_stats(cpu, hd);
+               part_stat_unlock();
+               seq_printf(seqf, "%4d %7d %s %lu %lu %llu "
                           "%u %lu %lu %llu %u %u %u %u\n",
-                          gp->major, n + gp->first_minor + 1,
-                          disk_name(gp, n + 1, buf),
+                          MAJOR(part_devt(hd)), MINOR(part_devt(hd)),
+                          disk_name(gp, hd->partno, buf),
                           part_stat_read(hd, ios[0]),
                           part_stat_read(hd, merges[0]),
                           (unsigned long long)part_stat_read(hd, sectors[0]),
@@ -668,14 +988,15 @@ static int diskstats_show(struct seq_file *s, void *v)
                           jiffies_to_msecs(part_stat_read(hd, time_in_queue))
                        );
        }
+       disk_part_iter_exit(&piter);
  
        return 0;
 }
 
 const struct seq_operations diskstats_op = {
-       .start  = diskstats_start,
-       .next   = diskstats_next,
-       .stop   = diskstats_stop,
+       .start  = disk_seqf_start,
+       .next   = disk_seqf_next,
+       .stop   = disk_seqf_stop,
        .show   = diskstats_show
 };
 #endif /* CONFIG_PROC_FS */
@@ -690,7 +1011,7 @@ static void media_change_notify_thread(struct work_struct *work)
         * set enviroment vars to indicate which event this is for
         * so that user space will know to go check the media status.
         */
-       kobject_uevent_env(&gd->dev.kobj, KOBJ_CHANGE, envp);
+       kobject_uevent_env(&disk_to_dev(gd)->kobj, KOBJ_CHANGE, envp);
        put_device(gd->driverfs_dev);
 }
 
@@ -703,42 +1024,29 @@ void genhd_media_change_notify(struct gendisk *disk)
 EXPORT_SYMBOL_GPL(genhd_media_change_notify);
 #endif  /*  0  */
 
-struct find_block {
-       const char *name;
-       int part;
-};
-
-static int match_id(struct device *dev, void *data)
+dev_t blk_lookup_devt(const char *name, int partno)
 {
-       struct find_block *find = data;
+       dev_t devt = MKDEV(0, 0);
+       struct class_dev_iter iter;
+       struct device *dev;
 
-       if (dev->type != &disk_type)
-               return 0;
-       if (strcmp(dev->bus_id, find->name) == 0) {
+       class_dev_iter_init(&iter, &block_class, NULL, &disk_type);
+       while ((dev = class_dev_iter_next(&iter))) {
                struct gendisk *disk = dev_to_disk(dev);
-               if (find->part < disk->minors)
-                       return 1;
-       }
-       return 0;
-}
+               struct hd_struct *part;
 
-dev_t blk_lookup_devt(const char *name, int part)
-{
-       struct device *dev;
-       dev_t devt = MKDEV(0, 0);
-       struct find_block find;
+               if (strcmp(dev->bus_id, name))
+                       continue;
 
-       mutex_lock(&block_class_lock);
-       find.name = name;
-       find.part = part;
-       dev = class_find_device(&block_class, NULL, &find, match_id);
-       if (dev) {
-               put_device(dev);
-               devt = MKDEV(MAJOR(dev->devt),
-                            MINOR(dev->devt) + part);
+               part = disk_get_part(disk, partno);
+               if (part) {
+                       devt = part_devt(part);
+                       disk_put_part(part);
+                       break;
+               }
+               disk_put_part(part);
        }
-       mutex_unlock(&block_class_lock);
-
+       class_dev_iter_exit(&iter);
        return devt;
 }
 EXPORT_SYMBOL(blk_lookup_devt);
@@ -747,6 +1055,7 @@ struct gendisk *alloc_disk(int minors)
 {
        return alloc_disk_node(minors, -1);
 }
+EXPORT_SYMBOL(alloc_disk);
 
 struct gendisk *alloc_disk_node(int minors, int node_id)
 {
@@ -755,32 +1064,28 @@ struct gendisk *alloc_disk_node(int minors, int node_id)
        disk = kmalloc_node(sizeof(struct gendisk),
                                GFP_KERNEL | __GFP_ZERO, node_id);
        if (disk) {
-               if (!init_disk_stats(disk)) {
+               if (!init_part_stats(&disk->part0)) {
                        kfree(disk);
                        return NULL;
                }
-               if (minors > 1) {
-                       int size = (minors - 1) * sizeof(struct hd_struct *);
-                       disk->part = kmalloc_node(size,
-                               GFP_KERNEL | __GFP_ZERO, node_id);
-                       if (!disk->part) {
-                               free_disk_stats(disk);
-                               kfree(disk);
-                               return NULL;
-                       }
+               if (disk_expand_part_tbl(disk, 0)) {
+                       free_part_stats(&disk->part0);
+                       kfree(disk);
+                       return NULL;
                }
+               disk->part_tbl->part[0] = &disk->part0;
+
                disk->minors = minors;
                rand_initialize_disk(disk);
-               disk->dev.class = &block_class;
-               disk->dev.type = &disk_type;
-               device_initialize(&disk->dev);
+               disk_to_dev(disk)->class = &block_class;
+               disk_to_dev(disk)->type = &disk_type;
+               device_initialize(disk_to_dev(disk));
                INIT_WORK(&disk->async_notify,
                        media_change_notify_thread);
+               disk->node_id = node_id;
        }
        return disk;
 }
-
-EXPORT_SYMBOL(alloc_disk);
 EXPORT_SYMBOL(alloc_disk_node);
 
 struct kobject *get_disk(struct gendisk *disk)
@@ -793,7 +1098,7 @@ struct kobject *get_disk(struct gendisk *disk)
        owner = disk->fops->owner;
        if (owner && !try_module_get(owner))
                return NULL;
-       kobj = kobject_get(&disk->dev.kobj);
+       kobj = kobject_get(&disk_to_dev(disk)->kobj);
        if (kobj == NULL) {
                module_put(owner);
                return NULL;
@@ -807,27 +1112,28 @@ EXPORT_SYMBOL(get_disk);
 void put_disk(struct gendisk *disk)
 {
        if (disk)
-               kobject_put(&disk->dev.kobj);
+               kobject_put(&disk_to_dev(disk)->kobj);
 }
 
 EXPORT_SYMBOL(put_disk);
 
 void set_device_ro(struct block_device *bdev, int flag)
 {
-       if (bdev->bd_contains != bdev)
-               bdev->bd_part->policy = flag;
-       else
-               bdev->bd_disk->policy = flag;
+       bdev->bd_part->policy = flag;
 }
 
 EXPORT_SYMBOL(set_device_ro);
 
 void set_disk_ro(struct gendisk *disk, int flag)
 {
-       int i;
-       disk->policy = flag;
-       for (i = 0; i < disk->minors - 1; i++)
-               if (disk->part[i]) disk->part[i]->policy = flag;
+       struct disk_part_iter piter;
+       struct hd_struct *part;
+
+       disk_part_iter_init(&piter, disk,
+                           DISK_PITER_INCL_EMPTY | DISK_PITER_INCL_PART0);
+       while ((part = disk_part_iter_next(&piter)))
+               part->policy = flag;
+       disk_part_iter_exit(&piter);
 }
 
 EXPORT_SYMBOL(set_disk_ro);
@@ -836,18 +1142,15 @@ int bdev_read_only(struct block_device *bdev)
 {
        if (!bdev)
                return 0;
-       else if (bdev->bd_contains != bdev)
-               return bdev->bd_part->policy;
-       else
-               return bdev->bd_disk->policy;
+       return bdev->bd_part->policy;
 }
 
 EXPORT_SYMBOL(bdev_read_only);
 
-int invalidate_partition(struct gendisk *disk, int index)
+int invalidate_partition(struct gendisk *disk, int partno)
 {
        int res = 0;
-       struct block_device *bdev = bdget_disk(disk, index);
+       struct block_device *bdev = bdget_disk(disk, partno);
        if (bdev) {
                fsync_bdev(bdev);
                res = __invalidate_device(bdev);
index 77185e5c026a659e300c69b276de3c5ccbb7327b..38bee321e1fa07c7dd41940c6fae8094a822068c 100644 (file)
@@ -12,11 +12,12 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user
 {
        struct block_device *bdevp;
        struct gendisk *disk;
+       struct hd_struct *part;
        struct blkpg_ioctl_arg a;
        struct blkpg_partition p;
+       struct disk_part_iter piter;
        long long start, length;
-       int part;
-       int i;
+       int partno;
        int err;
 
        if (!capable(CAP_SYS_ADMIN))
@@ -28,8 +29,8 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user
        disk = bdev->bd_disk;
        if (bdev != bdev->bd_contains)
                return -EINVAL;
-       part = p.pno;
-       if (part <= 0 || part >= disk->minors)
+       partno = p.pno;
+       if (partno <= 0)
                return -EINVAL;
        switch (a.op) {
                case BLKPG_ADD_PARTITION:
@@ -43,36 +44,37 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user
                                    || pstart < 0 || plength < 0)
                                        return -EINVAL;
                        }
-                       /* partition number in use? */
+
                        mutex_lock(&bdev->bd_mutex);
-                       if (disk->part[part - 1]) {
-                               mutex_unlock(&bdev->bd_mutex);
-                               return -EBUSY;
-                       }
-                       /* overlap? */
-                       for (i = 0; i < disk->minors - 1; i++) {
-                               struct hd_struct *s = disk->part[i];
 
-                               if (!s)
-                                       continue;
-                               if (!(start+length <= s->start_sect ||
-                                     start >= s->start_sect + s->nr_sects)) {
+                       /* overlap? */
+                       disk_part_iter_init(&piter, disk,
+                                           DISK_PITER_INCL_EMPTY);
+                       while ((part = disk_part_iter_next(&piter))) {
+                               if (!(start + length <= part->start_sect ||
+                                     start >= part->start_sect + part->nr_sects)) {
+                                       disk_part_iter_exit(&piter);
                                        mutex_unlock(&bdev->bd_mutex);
                                        return -EBUSY;
                                }
                        }
+                       disk_part_iter_exit(&piter);
+
                        /* all seems OK */
-                       err = add_partition(disk, part, start, length, ADDPART_FLAG_NONE);
+                       err = add_partition(disk, partno, start, length,
+                                           ADDPART_FLAG_NONE);
                        mutex_unlock(&bdev->bd_mutex);
                        return err;
                case BLKPG_DEL_PARTITION:
-                       if (!disk->part[part-1])
-                               return -ENXIO;
-                       if (disk->part[part - 1]->nr_sects == 0)
+                       part = disk_get_part(disk, partno);
+                       if (!part)
                                return -ENXIO;
-                       bdevp = bdget_disk(disk, part);
+
+                       bdevp = bdget(part_devt(part));
+                       disk_put_part(part);
                        if (!bdevp)
                                return -ENOMEM;
+
                        mutex_lock(&bdevp->bd_mutex);
                        if (bdevp->bd_openers) {
                                mutex_unlock(&bdevp->bd_mutex);
@@ -84,7 +86,7 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user
                        invalidate_bdev(bdevp);
 
                        mutex_lock_nested(&bdev->bd_mutex, 1);
-                       delete_partition(disk, part);
+                       delete_partition(disk, partno);
                        mutex_unlock(&bdev->bd_mutex);
                        mutex_unlock(&bdevp->bd_mutex);
                        bdput(bdevp);
@@ -100,7 +102,7 @@ static int blkdev_reread_part(struct block_device *bdev)
        struct gendisk *disk = bdev->bd_disk;
        int res;
 
-       if (disk->minors == 1 || bdev != bdev->bd_contains)
+       if (!disk_partitionable(disk) || bdev != bdev->bd_contains)
                return -EINVAL;
        if (!capable(CAP_SYS_ADMIN))
                return -EACCES;
@@ -111,6 +113,69 @@ static int blkdev_reread_part(struct block_device *bdev)
        return res;
 }
 
+static void blk_ioc_discard_endio(struct bio *bio, int err)
+{
+       if (err) {
+               if (err == -EOPNOTSUPP)
+                       set_bit(BIO_EOPNOTSUPP, &bio->bi_flags);
+               clear_bit(BIO_UPTODATE, &bio->bi_flags);
+       }
+       complete(bio->bi_private);
+}
+
+static int blk_ioctl_discard(struct block_device *bdev, uint64_t start,
+                            uint64_t len)
+{
+       struct request_queue *q = bdev_get_queue(bdev);
+       int ret = 0;
+
+       if (start & 511)
+               return -EINVAL;
+       if (len & 511)
+               return -EINVAL;
+       start >>= 9;
+       len >>= 9;
+
+       if (start + len > (bdev->bd_inode->i_size >> 9))
+               return -EINVAL;
+
+       if (!q->prepare_discard_fn)
+               return -EOPNOTSUPP;
+
+       while (len && !ret) {
+               DECLARE_COMPLETION_ONSTACK(wait);
+               struct bio *bio;
+
+               bio = bio_alloc(GFP_KERNEL, 0);
+               if (!bio)
+                       return -ENOMEM;
+
+               bio->bi_end_io = blk_ioc_discard_endio;
+               bio->bi_bdev = bdev;
+               bio->bi_private = &wait;
+               bio->bi_sector = start;
+
+               if (len > q->max_hw_sectors) {
+                       bio->bi_size = q->max_hw_sectors << 9;
+                       len -= q->max_hw_sectors;
+                       start += q->max_hw_sectors;
+               } else {
+                       bio->bi_size = len << 9;
+                       len = 0;
+               }
+               submit_bio(DISCARD_NOBARRIER, bio);
+
+               wait_for_completion(&wait);
+
+               if (bio_flagged(bio, BIO_EOPNOTSUPP))
+                       ret = -EOPNOTSUPP;
+               else if (!bio_flagged(bio, BIO_UPTODATE))
+                       ret = -EIO;
+               bio_put(bio);
+       }
+       return ret;
+}
+
 static int put_ushort(unsigned long arg, unsigned short val)
 {
        return put_user(val, (unsigned short __user *)arg);
@@ -258,6 +323,19 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
                set_device_ro(bdev, n);
                unlock_kernel();
                return 0;
+
+       case BLKDISCARD: {
+               uint64_t range[2];
+
+               if (!(file->f_mode & FMODE_WRITE))
+                       return -EBADF;
+
+               if (copy_from_user(range, (void __user *)arg, sizeof(range)))
+                       return -EFAULT;
+
+               return blk_ioctl_discard(bdev, range[0], range[1]);
+       }
+
        case HDIO_GETGEO: {
                struct hd_geometry geo;
 
index ec4b7f2346264a13e368132079e829877181cf7f..c34272a348fe07fd22aec5c8d8ccc55c37cddf64 100644 (file)
@@ -185,6 +185,7 @@ void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter)
        __set_bit(GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL, filter->write_ok);
        __set_bit(GPCMD_LOAD_UNLOAD, filter->write_ok);
        __set_bit(GPCMD_SET_STREAMING, filter->write_ok);
+       __set_bit(GPCMD_SET_READ_AHEAD, filter->write_ok);
 }
 EXPORT_SYMBOL_GPL(blk_set_cmd_filter_defaults);
 
@@ -313,11 +314,12 @@ static int sg_io(struct file *file, struct request_queue *q,
                        goto out;
                }
 
-               ret = blk_rq_map_user_iov(q, rq, iov, hdr->iovec_count,
-                                         hdr->dxfer_len);
+               ret = blk_rq_map_user_iov(q, rq, NULL, iov, hdr->iovec_count,
+                                         hdr->dxfer_len, GFP_KERNEL);
                kfree(iov);
        } else if (hdr->dxfer_len)
-               ret = blk_rq_map_user(q, rq, hdr->dxferp, hdr->dxfer_len);
+               ret = blk_rq_map_user(q, rq, NULL, hdr->dxferp, hdr->dxfer_len,
+                                     GFP_KERNEL);
 
        if (ret)
                goto out;
index d83185915eeee034948f30af0ef755de7ed557a8..39dbd8e4dde13c2769a1acb71c8d9937f12b3499 100644 (file)
@@ -21,6 +21,14 @@ if CRYPTO
 
 comment "Crypto core or helper"
 
+config CRYPTO_FIPS
+       bool "FIPS 200 compliance"
+       help
+         This options enables the fips boot option which is
+         required if you want to system to operate in a FIPS 200
+         certification.  You should say no unless you know what
+         this is.
+
 config CRYPTO_ALGAPI
        tristate
        help
@@ -33,14 +41,21 @@ config CRYPTO_AEAD
 config CRYPTO_BLKCIPHER
        tristate
        select CRYPTO_ALGAPI
+       select CRYPTO_RNG
 
 config CRYPTO_HASH
        tristate
        select CRYPTO_ALGAPI
 
+config CRYPTO_RNG
+       tristate
+       select CRYPTO_ALGAPI
+
 config CRYPTO_MANAGER
        tristate "Cryptographic algorithm manager"
-       select CRYPTO_ALGAPI
+       select CRYPTO_AEAD
+       select CRYPTO_HASH
+       select CRYPTO_BLKCIPHER
        help
          Create default cryptographic template instantiations such as
          cbc(aes).
@@ -85,9 +100,7 @@ config CRYPTO_AUTHENC
 config CRYPTO_TEST
        tristate "Testing module"
        depends on m
-       select CRYPTO_ALGAPI
-       select CRYPTO_AEAD
-       select CRYPTO_BLKCIPHER
+       select CRYPTO_MANAGER
        help
          Quick & dirty crypto test module.
 
@@ -113,6 +126,7 @@ config CRYPTO_SEQIV
        tristate "Sequence Number IV Generator"
        select CRYPTO_AEAD
        select CRYPTO_BLKCIPHER
+       select CRYPTO_RNG
        help
          This IV generator generates an IV based on a sequence number by
          xoring it with a salt.  This algorithm is mainly useful for CTR
@@ -219,7 +233,19 @@ config CRYPTO_CRC32C
          Castagnoli, et al Cyclic Redundancy-Check Algorithm.  Used
          by iSCSI for header and data digests and by others.
          See Castagnoli93.  This implementation uses lib/libcrc32c.
-          Module will be crc32c.
+         Module will be crc32c.
+
+config CRYPTO_CRC32C_INTEL
+       tristate "CRC32c INTEL hardware acceleration"
+       depends on X86
+       select CRYPTO_HASH
+       help
+         In Intel processor with SSE4.2 supported, the processor will
+         support CRC32C implementation using hardware accelerated CRC32
+         instruction. This option will create 'crc32c-intel' module,
+         which will enable any routine to use the CRC32 instruction to
+         gain performance compared with software implementation.
+         Module will be crc32c-intel.
 
 config CRYPTO_MD4
        tristate "MD4 digest algorithm"
@@ -243,55 +269,58 @@ config CRYPTO_MICHAEL_MIC
          of the algorithm.
 
 config CRYPTO_RMD128
-  tristate "RIPEMD-128 digest algorithm"
-  select CRYPTO_ALGAPI
-  help
-    RIPEMD-128 (ISO/IEC 10118-3:2004).
+       tristate "RIPEMD-128 digest algorithm"
+       select CRYPTO_ALGAPI
+       help
+         RIPEMD-128 (ISO/IEC 10118-3:2004).
 
-    RIPEMD-128 is a 128-bit cryptographic hash function. It should only
-    to be used as a secure replacement for RIPEMD. For other use cases
-    RIPEMD-160 should be used.
+         RIPEMD-128 is a 128-bit cryptographic hash function. It should only
+         to be used as a secure replacement for RIPEMD. For other use cases
+         RIPEMD-160 should be used.
 
-    Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel.
-    See <http://home.esat.kuleuven.be/~bosselae/ripemd160.html>
+         Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel.
+         See <http://home.esat.kuleuven.be/~bosselae/ripemd160.html>
 
 config CRYPTO_RMD160
-  tristate "RIPEMD-160 digest algorithm"
-  select CRYPTO_ALGAPI
-  help
-    RIPEMD-160 (ISO/IEC 10118-3:2004).
+       tristate "RIPEMD-160 digest algorithm"
+       select CRYPTO_ALGAPI
+       help
+         RIPEMD-160 (ISO/IEC 10118-3:2004).
 
-    RIPEMD-160 is a 160-bit cryptographic hash function. It is intended
-    to be used as a secure replacement for the 128-bit hash functions
-    MD4, MD5 and it's predecessor RIPEMD (not to be confused with RIPEMD-128).
+         RIPEMD-160 is a 160-bit cryptographic hash function. It is intended
+         to be used as a secure replacement for the 128-bit hash functions
+         MD4, MD5 and it's predecessor RIPEMD
+         (not to be confused with RIPEMD-128).
 
-    It's speed is comparable to SHA1 and there are no known attacks against
-    RIPEMD-160.
+         It's speed is comparable to SHA1 and there are no known attacks
+         against RIPEMD-160.
 
-    Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel.
-    See <http://home.esat.kuleuven.be/~bosselae/ripemd160.html>
+         Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel.
+         See <http://home.esat.kuleuven.be/~bosselae/ripemd160.html>
 
 config CRYPTO_RMD256
-  tristate "RIPEMD-256 digest algorithm"
-  select CRYPTO_ALGAPI
-  help
-    RIPEMD-256 is an optional extension of RIPEMD-128 with a 256 bit hash.
-    It is intended for applications that require longer hash-results, without
-    needing a larger security level (than RIPEMD-128).
+       tristate "RIPEMD-256 digest algorithm"
+       select CRYPTO_ALGAPI
+       help
+         RIPEMD-256 is an optional extension of RIPEMD-128 with a
+         256 bit hash. It is intended for applications that require
+         longer hash-results, without needing a larger security level
+         (than RIPEMD-128).
 
-    Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel.
-    See <http://home.esat.kuleuven.be/~bosselae/ripemd160.html>
+         Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel.
+         See <http://home.esat.kuleuven.be/~bosselae/ripemd160.html>
 
 config CRYPTO_RMD320
-  tristate "RIPEMD-320 digest algorithm"
-  select CRYPTO_ALGAPI
-  help
-    RIPEMD-320 is an optional extension of RIPEMD-160 with a 320 bit hash.
-    It is intended for applications that require longer hash-results, without
-    needing a larger security level (than RIPEMD-160).
+       tristate "RIPEMD-320 digest algorithm"
+       select CRYPTO_ALGAPI
+       help
+         RIPEMD-320 is an optional extension of RIPEMD-160 with a
+         320 bit hash. It is intended for applications that require
+         longer hash-results, without needing a larger security level
+         (than RIPEMD-160).
 
-    Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel.
-    See <http://home.esat.kuleuven.be/~bosselae/ripemd160.html>
+         Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel.
+         See <http://home.esat.kuleuven.be/~bosselae/ripemd160.html>
 
 config CRYPTO_SHA1
        tristate "SHA1 digest algorithm"
@@ -308,8 +337,8 @@ config CRYPTO_SHA256
          This version of SHA implements a 256 bit hash with 128 bits of
          security against collision attacks.
 
-          This code also includes SHA-224, a 224 bit hash with 112 bits
-          of security against collision attacks.
+         This code also includes SHA-224, a 224 bit hash with 112 bits
+         of security against collision attacks.
 
 config CRYPTO_SHA512
        tristate "SHA384 and SHA512 digest algorithms"
@@ -666,6 +695,18 @@ config CRYPTO_LZO
        help
          This is the LZO algorithm.
 
+comment "Random Number Generation"
+
+config CRYPTO_ANSI_CPRNG
+       tristate "Pseudo Random Number Generation for Cryptographic modules"
+       select CRYPTO_AES
+       select CRYPTO_RNG
+       select CRYPTO_FIPS
+       help
+         This option enables the generic pseudo random number generator
+         for cryptographic modules.  Uses the Algorithm specified in
+         ANSI X9.31 A.2.4
+
 source "drivers/crypto/Kconfig"
 
 endif  # if CRYPTO
index d4f3ed857df01bc376aee37a54bb7d2186c529a3..5862b807334e5c0f46fbad14bf01e058fe4e9939 100644 (file)
@@ -5,6 +5,8 @@
 obj-$(CONFIG_CRYPTO) += crypto.o
 crypto-objs := api.o cipher.o digest.o compress.o
 
+obj-$(CONFIG_CRYPTO_FIPS) += fips.o
+
 crypto_algapi-$(CONFIG_PROC_FS) += proc.o
 crypto_algapi-objs := algapi.o scatterwalk.o $(crypto_algapi-y)
 obj-$(CONFIG_CRYPTO_ALGAPI) += crypto_algapi.o
@@ -13,15 +15,17 @@ obj-$(CONFIG_CRYPTO_AEAD) += aead.o
 
 crypto_blkcipher-objs := ablkcipher.o
 crypto_blkcipher-objs += blkcipher.o
-crypto_blkcipher-objs += chainiv.o
-crypto_blkcipher-objs += eseqiv.o
 obj-$(CONFIG_CRYPTO_BLKCIPHER) += crypto_blkcipher.o
+obj-$(CONFIG_CRYPTO_BLKCIPHER) += chainiv.o
+obj-$(CONFIG_CRYPTO_BLKCIPHER) += eseqiv.o
 obj-$(CONFIG_CRYPTO_SEQIV) += seqiv.o
 
 crypto_hash-objs := hash.o
 crypto_hash-objs += ahash.o
 obj-$(CONFIG_CRYPTO_HASH) += crypto_hash.o
 
+cryptomgr-objs := algboss.o testmgr.o
+
 obj-$(CONFIG_CRYPTO_MANAGER) += cryptomgr.o
 obj-$(CONFIG_CRYPTO_HMAC) += hmac.o
 obj-$(CONFIG_CRYPTO_XCBC) += xcbc.o
@@ -69,7 +73,9 @@ obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o
 obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o
 obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o
 obj-$(CONFIG_CRYPTO_LZO) += lzo.o
-
+obj-$(CONFIG_CRYPTO_RNG) += rng.o
+obj-$(CONFIG_CRYPTO_RNG) += krng.o
+obj-$(CONFIG_CRYPTO_ANSI_CPRNG) += ansi_cprng.o
 obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
 
 #
index e65cb50cf4aff8b739130ba7012e383196ef286a..7c41e7405c41a4392791cc4a01a22cce52f983b0 100644 (file)
 
 #include "internal.h"
 
+static void crypto_remove_final(struct list_head *list);
+
 static LIST_HEAD(crypto_template_list);
 
 void crypto_larval_error(const char *name, u32 type, u32 mask)
 {
        struct crypto_alg *alg;
 
-       down_read(&crypto_alg_sem);
-       alg = __crypto_alg_lookup(name, type, mask);
-       up_read(&crypto_alg_sem);
+       alg = crypto_alg_lookup(name, type, mask);
 
        if (alg) {
                if (crypto_is_larval(alg)) {
@@ -128,23 +128,97 @@ static void crypto_remove_spawns(struct list_head *spawns,
        }
 }
 
-static int __crypto_register_alg(struct crypto_alg *alg,
-                                struct list_head *list)
+static struct crypto_larval *__crypto_register_alg(struct crypto_alg *alg)
 {
        struct crypto_alg *q;
+       struct crypto_larval *larval;
        int ret = -EAGAIN;
 
        if (crypto_is_dead(alg))
-               goto out;
+               goto err;
 
        INIT_LIST_HEAD(&alg->cra_users);
 
+       /* No cheating! */
+       alg->cra_flags &= ~CRYPTO_ALG_TESTED;
+
        ret = -EEXIST;
 
        atomic_set(&alg->cra_refcnt, 1);
        list_for_each_entry(q, &crypto_alg_list, cra_list) {
                if (q == alg)
-                       goto out;
+                       goto err;
+
+               if (crypto_is_larval(q)) {
+                       if (!strcmp(alg->cra_driver_name, q->cra_driver_name))
+                               goto err;
+                       continue;
+               }
+
+               if (!strcmp(q->cra_driver_name, alg->cra_name) ||
+                   !strcmp(q->cra_name, alg->cra_driver_name))
+                       goto err;
+       }
+
+       larval = crypto_larval_alloc(alg->cra_name,
+                                    alg->cra_flags | CRYPTO_ALG_TESTED, 0);
+       if (IS_ERR(larval))
+               goto out;
+
+       ret = -ENOENT;
+       larval->adult = crypto_mod_get(alg);
+       if (!larval->adult)
+               goto free_larval;
+
+       atomic_set(&larval->alg.cra_refcnt, 1);
+       memcpy(larval->alg.cra_driver_name, alg->cra_driver_name,
+              CRYPTO_MAX_ALG_NAME);
+       larval->alg.cra_priority = alg->cra_priority;
+
+       list_add(&alg->cra_list, &crypto_alg_list);
+       list_add(&larval->alg.cra_list, &crypto_alg_list);
+
+out:   
+       return larval;
+
+free_larval:
+       kfree(larval);
+err:
+       larval = ERR_PTR(ret);
+       goto out;
+}
+
+void crypto_alg_tested(const char *name, int err)
+{
+       struct crypto_larval *test;
+       struct crypto_alg *alg;
+       struct crypto_alg *q;
+       LIST_HEAD(list);
+
+       down_write(&crypto_alg_sem);
+       list_for_each_entry(q, &crypto_alg_list, cra_list) {
+               if (!crypto_is_larval(q))
+                       continue;
+
+               test = (struct crypto_larval *)q;
+
+               if (!strcmp(q->cra_driver_name, name))
+                       goto found;
+       }
+
+       printk(KERN_ERR "alg: Unexpected test result for %s: %d\n", name, err);
+       goto unlock;
+
+found:
+       alg = test->adult;
+       if (err || list_empty(&alg->cra_list))
+               goto complete;
+
+       alg->cra_flags |= CRYPTO_ALG_TESTED;
+
+       list_for_each_entry(q, &crypto_alg_list, cra_list) {
+               if (q == alg)
+                       continue;
 
                if (crypto_is_moribund(q))
                        continue;
@@ -180,17 +254,18 @@ static int __crypto_register_alg(struct crypto_alg *alg,
                    q->cra_priority > alg->cra_priority)
                        continue;
 
-               crypto_remove_spawns(&q->cra_users, list, alg->cra_flags);
+               crypto_remove_spawns(&q->cra_users, &list, alg->cra_flags);
        }
-       
-       list_add(&alg->cra_list, &crypto_alg_list);
 
-       crypto_notify(CRYPTO_MSG_ALG_REGISTER, alg);
-       ret = 0;
+complete:
+       complete_all(&test->completion);
 
-out:   
-       return ret;
+unlock:
+       up_write(&crypto_alg_sem);
+
+       crypto_remove_final(&list);
 }
+EXPORT_SYMBOL_GPL(crypto_alg_tested);
 
 static void crypto_remove_final(struct list_head *list)
 {
@@ -203,9 +278,27 @@ static void crypto_remove_final(struct list_head *list)
        }
 }
 
+static void crypto_wait_for_test(struct crypto_larval *larval)
+{
+       int err;
+
+       err = crypto_probing_notify(CRYPTO_MSG_ALG_REGISTER, larval->adult);
+       if (err != NOTIFY_STOP) {
+               if (WARN_ON(err != NOTIFY_DONE))
+                       goto out;
+               crypto_alg_tested(larval->alg.cra_driver_name, 0);
+       }
+
+       err = wait_for_completion_interruptible(&larval->completion);
+       WARN_ON(err);
+
+out:
+       crypto_larval_kill(&larval->alg);
+}
+
 int crypto_register_alg(struct crypto_alg *alg)
 {
-       LIST_HEAD(list);
+       struct crypto_larval *larval;
        int err;
 
        err = crypto_check_alg(alg);
@@ -213,11 +306,14 @@ int crypto_register_alg(struct crypto_alg *alg)
                return err;
 
        down_write(&crypto_alg_sem);
-       err = __crypto_register_alg(alg, &list);
+       larval = __crypto_register_alg(alg);
        up_write(&crypto_alg_sem);
 
-       crypto_remove_final(&list);
-       return err;
+       if (IS_ERR(larval))
+               return PTR_ERR(larval);
+
+       crypto_wait_for_test(larval);
+       return 0;
 }
 EXPORT_SYMBOL_GPL(crypto_register_alg);
 
@@ -335,8 +431,8 @@ EXPORT_SYMBOL_GPL(crypto_lookup_template);
 int crypto_register_instance(struct crypto_template *tmpl,
                             struct crypto_instance *inst)
 {
-       LIST_HEAD(list);
-       int err = -EINVAL;
+       struct crypto_larval *larval;
+       int err;
 
        err = crypto_check_alg(&inst->alg);
        if (err)
@@ -346,8 +442,8 @@ int crypto_register_instance(struct crypto_template *tmpl,
 
        down_write(&crypto_alg_sem);
 
-       err = __crypto_register_alg(&inst->alg, &list);
-       if (err)
+       larval = __crypto_register_alg(&inst->alg);
+       if (IS_ERR(larval))
                goto unlock;
 
        hlist_add_head(&inst->list, &tmpl->instances);
@@ -356,7 +452,12 @@ int crypto_register_instance(struct crypto_template *tmpl,
 unlock:
        up_write(&crypto_alg_sem);
 
-       crypto_remove_final(&list);
+       err = PTR_ERR(larval);
+       if (IS_ERR(larval))
+               goto err;
+
+       crypto_wait_for_test(larval);
+       err = 0;
 
 err:
        return err;
similarity index 69%
rename from crypto/cryptomgr.c
rename to crypto/algboss.c
index e5e3cf848d425ad0c3fa8584e323b51d9135221b..4601e4267c886182d6b037983fe2630fffb5d8dd 100644 (file)
@@ -45,6 +45,15 @@ struct cryptomgr_param {
 
        char larval[CRYPTO_MAX_ALG_NAME];
        char template[CRYPTO_MAX_ALG_NAME];
+
+       u32 otype;
+       u32 omask;
+};
+
+struct crypto_test_param {
+       char driver[CRYPTO_MAX_ALG_NAME];
+       char alg[CRYPTO_MAX_ALG_NAME];
+       u32 type;
 };
 
 static int cryptomgr_probe(void *data)
@@ -76,8 +85,7 @@ out:
        module_put_and_exit(0);
 
 err:
-       crypto_larval_error(param->larval, param->type.data.type,
-                           param->type.data.mask);
+       crypto_larval_error(param->larval, param->otype, param->omask);
        goto out;
 }
 
@@ -169,13 +177,65 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval)
 
        param->type.attr.rta_len = sizeof(param->type);
        param->type.attr.rta_type = CRYPTOA_TYPE;
-       param->type.data.type = larval->alg.cra_flags;
-       param->type.data.mask = larval->mask;
+       param->type.data.type = larval->alg.cra_flags & ~CRYPTO_ALG_TESTED;
+       param->type.data.mask = larval->mask & ~CRYPTO_ALG_TESTED;
        param->tb[0] = &param->type.attr;
 
+       param->otype = larval->alg.cra_flags;
+       param->omask = larval->mask;
+
        memcpy(param->larval, larval->alg.cra_name, CRYPTO_MAX_ALG_NAME);
 
-       thread = kthread_run(cryptomgr_probe, param, "cryptomgr");
+       thread = kthread_run(cryptomgr_probe, param, "cryptomgr_probe");
+       if (IS_ERR(thread))
+               goto err_free_param;
+
+       return NOTIFY_STOP;
+
+err_free_param:
+       kfree(param);
+err_put_module:
+       module_put(THIS_MODULE);
+err:
+       return NOTIFY_OK;
+}
+
+static int cryptomgr_test(void *data)
+{
+       struct crypto_test_param *param = data;
+       u32 type = param->type;
+       int err = 0;
+
+       if (!((type ^ CRYPTO_ALG_TYPE_BLKCIPHER) &
+             CRYPTO_ALG_TYPE_BLKCIPHER_MASK) && !(type & CRYPTO_ALG_GENIV))
+               goto skiptest;
+
+       err = alg_test(param->driver, param->alg, type, CRYPTO_ALG_TESTED);
+
+skiptest:
+       crypto_alg_tested(param->driver, err);
+
+       kfree(param);
+       module_put_and_exit(0);
+}
+
+static int cryptomgr_schedule_test(struct crypto_alg *alg)
+{
+       struct task_struct *thread;
+       struct crypto_test_param *param;
+
+       if (!try_module_get(THIS_MODULE))
+               goto err;
+
+       param = kzalloc(sizeof(*param), GFP_KERNEL);
+       if (!param)
+               goto err_put_module;
+
+       memcpy(param->driver, alg->cra_driver_name, sizeof(param->driver));
+       memcpy(param->alg, alg->cra_name, sizeof(param->alg));
+       param->type = alg->cra_flags;
+
+       thread = kthread_run(cryptomgr_test, param, "cryptomgr_test");
        if (IS_ERR(thread))
                goto err_free_param;
 
@@ -195,6 +255,8 @@ static int cryptomgr_notify(struct notifier_block *this, unsigned long msg,
        switch (msg) {
        case CRYPTO_MSG_ALG_REQUEST:
                return cryptomgr_schedule_probe(data);
+       case CRYPTO_MSG_ALG_REGISTER:
+               return cryptomgr_schedule_test(data);
        }
 
        return NOTIFY_DONE;
@@ -206,16 +268,32 @@ static struct notifier_block cryptomgr_notifier = {
 
 static int __init cryptomgr_init(void)
 {
-       return crypto_register_notifier(&cryptomgr_notifier);
+       int err;
+
+       err = testmgr_init();
+       if (err)
+               return err;
+
+       err = crypto_register_notifier(&cryptomgr_notifier);
+       if (err)
+               goto free_testmgr;
+
+       return 0;
+
+free_testmgr:
+       testmgr_exit();
+       return err;
 }
 
 static void __exit cryptomgr_exit(void)
 {
        int err = crypto_unregister_notifier(&cryptomgr_notifier);
        BUG_ON(err);
+
+       testmgr_exit();
 }
 
-module_init(cryptomgr_init);
+subsys_initcall(cryptomgr_init);
 module_exit(cryptomgr_exit);
 
 MODULE_LICENSE("GPL");
diff --git a/crypto/ansi_cprng.c b/crypto/ansi_cprng.c
new file mode 100644 (file)
index 0000000..72db0fd
--- /dev/null
@@ -0,0 +1,417 @@
+/*
+ * PRNG: Pseudo Random Number Generator
+ *       Based on NIST Recommended PRNG From ANSI X9.31 Appendix A.2.4 using
+ *       AES 128 cipher
+ *
+ *  (C) Neil Horman <nhorman@tuxdriver.com>
+ *
+ *  This program 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
+ *  any later version.
+ *
+ *
+ */
+
+#include <crypto/internal/rng.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/string.h>
+
+#include "internal.h"
+
+#define DEFAULT_PRNG_KEY "0123456789abcdef"
+#define DEFAULT_PRNG_KSZ 16
+#define DEFAULT_BLK_SZ 16
+#define DEFAULT_V_SEED "zaybxcwdveuftgsh"
+
+/*
+ * Flags for the prng_context flags field
+ */
+
+#define PRNG_FIXED_SIZE 0x1
+#define PRNG_NEED_RESET 0x2
+
+/*
+ * Note: DT is our counter value
+ *      I is our intermediate value
+ *      V is our seed vector
+ * See http://csrc.nist.gov/groups/STM/cavp/documents/rng/931rngext.pdf
+ * for implementation details
+ */
+
+
+struct prng_context {
+       spinlock_t prng_lock;
+       unsigned char rand_data[DEFAULT_BLK_SZ];
+       unsigned char last_rand_data[DEFAULT_BLK_SZ];
+       unsigned char DT[DEFAULT_BLK_SZ];
+       unsigned char I[DEFAULT_BLK_SZ];
+       unsigned char V[DEFAULT_BLK_SZ];
+       u32 rand_data_valid;
+       struct crypto_cipher *tfm;
+       u32 flags;
+};
+
+static int dbg;
+
+static void hexdump(char *note, unsigned char *buf, unsigned int len)
+{
+       if (dbg) {
+               printk(KERN_CRIT "%s", note);
+               print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET,
+                               16, 1,
+                               buf, len, false);
+       }
+}
+
+#define dbgprint(format, args...) do {\
+if (dbg)\
+       printk(format, ##args);\
+} while (0)
+
+static void xor_vectors(unsigned char *in1, unsigned char *in2,
+                       unsigned char *out, unsigned int size)
+{
+       int i;
+
+       for (i = 0; i < size; i++)
+               out[i] = in1[i] ^ in2[i];
+
+}
+/*
+ * Returns DEFAULT_BLK_SZ bytes of random data per call
+ * returns 0 if generation succeded, <0 if something went wrong
+ */
+static int _get_more_prng_bytes(struct prng_context *ctx)
+{
+       int i;
+       unsigned char tmp[DEFAULT_BLK_SZ];
+       unsigned char *output = NULL;
+
+
+       dbgprint(KERN_CRIT "Calling _get_more_prng_bytes for context %p\n",
+               ctx);
+
+       hexdump("Input DT: ", ctx->DT, DEFAULT_BLK_SZ);
+       hexdump("Input I: ", ctx->I, DEFAULT_BLK_SZ);
+       hexdump("Input V: ", ctx->V, DEFAULT_BLK_SZ);
+
+       /*
+        * This algorithm is a 3 stage state machine
+        */
+       for (i = 0; i < 3; i++) {
+
+               switch (i) {
+               case 0:
+                       /*
+                        * Start by encrypting the counter value
+                        * This gives us an intermediate value I
+                        */
+                       memcpy(tmp, ctx->DT, DEFAULT_BLK_SZ);
+                       output = ctx->I;
+                       hexdump("tmp stage 0: ", tmp, DEFAULT_BLK_SZ);
+                       break;
+               case 1:
+
+                       /*
+                        * Next xor I with our secret vector V
+                        * encrypt that result to obtain our
+                        * pseudo random data which we output
+                        */
+                       xor_vectors(ctx->I, ctx->V, tmp, DEFAULT_BLK_SZ);
+                       hexdump("tmp stage 1: ", tmp, DEFAULT_BLK_SZ);
+                       output = ctx->rand_data;
+                       break;
+               case 2:
+                       /*
+                        * First check that we didn't produce the same
+                        * random data that we did last time around through this
+                        */
+                       if (!memcmp(ctx->rand_data, ctx->last_rand_data,
+                                       DEFAULT_BLK_SZ)) {
+                               printk(KERN_ERR
+                                       "ctx %p Failed repetition check!\n",
+                                       ctx);
+                               ctx->flags |= PRNG_NEED_RESET;
+                               return -EINVAL;
+                       }
+                       memcpy(ctx->last_rand_data, ctx->rand_data,
+                               DEFAULT_BLK_SZ);
+
+                       /*
+                        * Lastly xor the random data with I
+                        * and encrypt that to obtain a new secret vector V
+                        */
+                       xor_vectors(ctx->rand_data, ctx->I, tmp,
+                               DEFAULT_BLK_SZ);
+                       output = ctx->V;
+                       hexdump("tmp stage 2: ", tmp, DEFAULT_BLK_SZ);
+                       break;
+               }
+
+
+               /* do the encryption */
+               crypto_cipher_encrypt_one(ctx->tfm, output, tmp);
+
+       }
+
+       /*
+        * Now update our DT value
+        */
+       for (i = 0; i < DEFAULT_BLK_SZ; i++) {
+               ctx->DT[i] += 1;
+               if (ctx->DT[i] != 0)
+                       break;
+       }
+
+       dbgprint("Returning new block for context %p\n", ctx);
+       ctx->rand_data_valid = 0;
+
+       hexdump("Output DT: ", ctx->DT, DEFAULT_BLK_SZ);
+       hexdump("Output I: ", ctx->I, DEFAULT_BLK_SZ);
+       hexdump("Output V: ", ctx->V, DEFAULT_BLK_SZ);
+       hexdump("New Random Data: ", ctx->rand_data, DEFAULT_BLK_SZ);
+
+       return 0;
+}
+
+/* Our exported functions */
+static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx)
+{
+       unsigned long flags;
+       unsigned char *ptr = buf;
+       unsigned int byte_count = (unsigned int)nbytes;
+       int err;
+
+
+       if (nbytes < 0)
+               return -EINVAL;
+
+       spin_lock_irqsave(&ctx->prng_lock, flags);
+
+       err = -EINVAL;
+       if (ctx->flags & PRNG_NEED_RESET)
+               goto done;
+
+       /*
+        * If the FIXED_SIZE flag is on, only return whole blocks of
+        * pseudo random data
+        */
+       err = -EINVAL;
+       if (ctx->flags & PRNG_FIXED_SIZE) {
+               if (nbytes < DEFAULT_BLK_SZ)
+                       goto done;
+               byte_count = DEFAULT_BLK_SZ;
+       }
+
+       err = byte_count;
+
+       dbgprint(KERN_CRIT "getting %d random bytes for context %p\n",
+               byte_count, ctx);
+
+
+remainder:
+       if (ctx->rand_data_valid == DEFAULT_BLK_SZ) {
+               if (_get_more_prng_bytes(ctx) < 0) {
+                       memset(buf, 0, nbytes);
+                       err = -EINVAL;
+                       goto done;
+               }
+       }
+
+       /*
+        * Copy up to the next whole block size
+        */
+       if (byte_count < DEFAULT_BLK_SZ) {
+               for (; ctx->rand_data_valid < DEFAULT_BLK_SZ;
+                       ctx->rand_data_valid++) {
+                       *ptr = ctx->rand_data[ctx->rand_data_valid];
+                       ptr++;
+                       byte_count--;
+                       if (byte_count == 0)
+                               goto done;
+               }
+       }
+
+       /*
+        * Now copy whole blocks
+        */
+       for (; byte_count >= DEFAULT_BLK_SZ; byte_count -= DEFAULT_BLK_SZ) {
+               if (_get_more_prng_bytes(ctx) < 0) {
+                       memset(buf, 0, nbytes);
+                       err = -EINVAL;
+                       goto done;
+               }
+               memcpy(ptr, ctx->rand_data, DEFAULT_BLK_SZ);
+               ctx->rand_data_valid += DEFAULT_BLK_SZ;
+               ptr += DEFAULT_BLK_SZ;
+       }
+
+       /*
+        * Now copy any extra partial data
+        */
+       if (byte_count)
+               goto remainder;
+
+done:
+       spin_unlock_irqrestore(&ctx->prng_lock, flags);
+       dbgprint(KERN_CRIT "returning %d from get_prng_bytes in context %p\n",
+               err, ctx);
+       return err;
+}
+
+static void free_prng_context(struct prng_context *ctx)
+{
+       crypto_free_cipher(ctx->tfm);
+}
+
+static int reset_prng_context(struct prng_context *ctx,
+                             unsigned char *key, size_t klen,
+                             unsigned char *V, unsigned char *DT)
+{
+       int ret;
+       int rc = -EINVAL;
+       unsigned char *prng_key;
+
+       spin_lock(&ctx->prng_lock);
+       ctx->flags |= PRNG_NEED_RESET;
+
+       prng_key = (key != NULL) ? key : (unsigned char *)DEFAULT_PRNG_KEY;
+
+       if (!key)
+               klen = DEFAULT_PRNG_KSZ;
+
+       if (V)
+               memcpy(ctx->V, V, DEFAULT_BLK_SZ);
+       else
+               memcpy(ctx->V, DEFAULT_V_SEED, DEFAULT_BLK_SZ);
+
+       if (DT)
+               memcpy(ctx->DT, DT, DEFAULT_BLK_SZ);
+       else
+               memset(ctx->DT, 0, DEFAULT_BLK_SZ);
+
+       memset(ctx->rand_data, 0, DEFAULT_BLK_SZ);
+       memset(ctx->last_rand_data, 0, DEFAULT_BLK_SZ);
+
+       if (ctx->tfm)
+               crypto_free_cipher(ctx->tfm);
+
+       ctx->tfm = crypto_alloc_cipher("aes", 0, 0);
+       if (IS_ERR(ctx->tfm)) {
+               dbgprint(KERN_CRIT "Failed to alloc tfm for context %p\n",
+                       ctx);
+               ctx->tfm = NULL;
+               goto out;
+       }
+
+       ctx->rand_data_valid = DEFAULT_BLK_SZ;
+
+       ret = crypto_cipher_setkey(ctx->tfm, prng_key, klen);
+       if (ret) {
+               dbgprint(KERN_CRIT "PRNG: setkey() failed flags=%x\n",
+                       crypto_cipher_get_flags(ctx->tfm));
+               crypto_free_cipher(ctx->tfm);
+               goto out;
+       }
+
+       rc = 0;
+       ctx->flags &= ~PRNG_NEED_RESET;
+out:
+       spin_unlock(&ctx->prng_lock);
+
+       return rc;
+
+}
+
+static int cprng_init(struct crypto_tfm *tfm)
+{
+       struct prng_context *ctx = crypto_tfm_ctx(tfm);
+
+       spin_lock_init(&ctx->prng_lock);
+
+       return reset_prng_context(ctx, NULL, DEFAULT_PRNG_KSZ, NULL, NULL);
+}
+
+static void cprng_exit(struct crypto_tfm *tfm)
+{
+       free_prng_context(crypto_tfm_ctx(tfm));
+}
+
+static int cprng_get_random(struct crypto_rng *tfm, u8 *rdata,
+                           unsigned int dlen)
+{
+       struct prng_context *prng = crypto_rng_ctx(tfm);
+
+       return get_prng_bytes(rdata, dlen, prng);
+}
+
+static int cprng_reset(struct crypto_rng *tfm, u8 *seed, unsigned int slen)
+{
+       struct prng_context *prng = crypto_rng_ctx(tfm);
+       u8 *key = seed + DEFAULT_PRNG_KSZ;
+
+       if (slen < DEFAULT_PRNG_KSZ + DEFAULT_BLK_SZ)
+               return -EINVAL;
+
+       reset_prng_context(prng, key, DEFAULT_PRNG_KSZ, seed, NULL);
+
+       if (prng->flags & PRNG_NEED_RESET)
+               return -EINVAL;
+       return 0;
+}
+
+static struct crypto_alg rng_alg = {
+       .cra_name               = "stdrng",
+       .cra_driver_name        = "ansi_cprng",
+       .cra_priority           = 100,
+       .cra_flags              = CRYPTO_ALG_TYPE_RNG,
+       .cra_ctxsize            = sizeof(struct prng_context),
+       .cra_type               = &crypto_rng_type,
+       .cra_module             = THIS_MODULE,
+       .cra_list               = LIST_HEAD_INIT(rng_alg.cra_list),
+       .cra_init               = cprng_init,
+       .cra_exit               = cprng_exit,
+       .cra_u                  = {
+               .rng = {
+                       .rng_make_random        = cprng_get_random,
+                       .rng_reset              = cprng_reset,
+                       .seedsize = DEFAULT_PRNG_KSZ + DEFAULT_BLK_SZ,
+               }
+       }
+};
+
+
+/* Module initalization */
+static int __init prng_mod_init(void)
+{
+       int ret = 0;
+
+       if (fips_enabled)
+               rng_alg.cra_priority += 200;
+
+       ret = crypto_register_alg(&rng_alg);
+
+       if (ret)
+               goto out;
+out:
+       return 0;
+}
+
+static void __exit prng_mod_fini(void)
+{
+       crypto_unregister_alg(&rng_alg);
+       return;
+}
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Software Pseudo Random Number Generator");
+MODULE_AUTHOR("Neil Horman <nhorman@tuxdriver.com>");
+module_param(dbg, int, 0);
+MODULE_PARM_DESC(dbg, "Boolean to enable debugging (0/1 == off/on)");
+module_init(prng_mod_init);
+module_exit(prng_mod_fini);
+MODULE_ALIAS("stdrng");
index d06e33270abea8fae3c5ae97354774bca63bf9b3..0444d242e9854dbc1a63a61a37ecc37b94c52df7 100644 (file)
@@ -55,7 +55,13 @@ void crypto_mod_put(struct crypto_alg *alg)
 }
 EXPORT_SYMBOL_GPL(crypto_mod_put);
 
-struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type, u32 mask)
+static inline int crypto_is_test_larval(struct crypto_larval *larval)
+{
+       return larval->alg.cra_driver_name[0];
+}
+
+static struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type,
+                                             u32 mask)
 {
        struct crypto_alg *q, *alg = NULL;
        int best = -2;
@@ -70,6 +76,7 @@ struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type, u32 mask)
                        continue;
 
                if (crypto_is_larval(q) &&
+                   !crypto_is_test_larval((struct crypto_larval *)q) &&
                    ((struct crypto_larval *)q)->mask != mask)
                        continue;
 
@@ -92,7 +99,6 @@ struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type, u32 mask)
 
        return alg;
 }
-EXPORT_SYMBOL_GPL(__crypto_alg_lookup);
 
 static void crypto_larval_destroy(struct crypto_alg *alg)
 {
@@ -104,10 +110,8 @@ static void crypto_larval_destroy(struct crypto_alg *alg)
        kfree(larval);
 }
 
-static struct crypto_alg *crypto_larval_alloc(const char *name, u32 type,
-                                             u32 mask)
+struct crypto_larval *crypto_larval_alloc(const char *name, u32 type, u32 mask)
 {
-       struct crypto_alg *alg;
        struct crypto_larval *larval;
 
        larval = kzalloc(sizeof(*larval), GFP_KERNEL);
@@ -119,10 +123,25 @@ static struct crypto_alg *crypto_larval_alloc(const char *name, u32 type,
        larval->alg.cra_priority = -1;
        larval->alg.cra_destroy = crypto_larval_destroy;
 
-       atomic_set(&larval->alg.cra_refcnt, 2);
        strlcpy(larval->alg.cra_name, name, CRYPTO_MAX_ALG_NAME);
        init_completion(&larval->completion);
 
+       return larval;
+}
+EXPORT_SYMBOL_GPL(crypto_larval_alloc);
+
+static struct crypto_alg *crypto_larval_add(const char *name, u32 type,
+                                           u32 mask)
+{
+       struct crypto_alg *alg;
+       struct crypto_larval *larval;
+
+       larval = crypto_larval_alloc(name, type, mask);
+       if (IS_ERR(larval))
+               return ERR_CAST(larval);
+
+       atomic_set(&larval->alg.cra_refcnt, 2);
+
        down_write(&crypto_alg_sem);
        alg = __crypto_alg_lookup(name, type, mask);
        if (!alg) {
@@ -152,21 +171,29 @@ EXPORT_SYMBOL_GPL(crypto_larval_kill);
 static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg)
 {
        struct crypto_larval *larval = (void *)alg;
+       long timeout;
+
+       timeout = wait_for_completion_interruptible_timeout(
+               &larval->completion, 60 * HZ);
 
-       wait_for_completion_interruptible_timeout(&larval->completion, 60 * HZ);
        alg = larval->adult;
-       if (alg) {
-               if (!crypto_mod_get(alg))
-                       alg = ERR_PTR(-EAGAIN);
-       } else
+       if (timeout < 0)
+               alg = ERR_PTR(-EINTR);
+       else if (!timeout)
+               alg = ERR_PTR(-ETIMEDOUT);
+       else if (!alg)
                alg = ERR_PTR(-ENOENT);
+       else if (crypto_is_test_larval(larval) &&
+                !(alg->cra_flags & CRYPTO_ALG_TESTED))
+               alg = ERR_PTR(-EAGAIN);
+       else if (!crypto_mod_get(alg))
+               alg = ERR_PTR(-EAGAIN);
        crypto_mod_put(&larval->alg);
 
        return alg;
 }
 
-static struct crypto_alg *crypto_alg_lookup(const char *name, u32 type,
-                                           u32 mask)
+struct crypto_alg *crypto_alg_lookup(const char *name, u32 type, u32 mask)
 {
        struct crypto_alg *alg;
 
@@ -176,6 +203,7 @@ static struct crypto_alg *crypto_alg_lookup(const char *name, u32 type,
 
        return alg;
 }
+EXPORT_SYMBOL_GPL(crypto_alg_lookup);
 
 struct crypto_alg *crypto_larval_lookup(const char *name, u32 type, u32 mask)
 {
@@ -192,25 +220,40 @@ struct crypto_alg *crypto_larval_lookup(const char *name, u32 type, u32 mask)
        if (alg)
                return crypto_is_larval(alg) ? crypto_larval_wait(alg) : alg;
 
-       return crypto_larval_alloc(name, type, mask);
+       return crypto_larval_add(name, type, mask);
 }
 EXPORT_SYMBOL_GPL(crypto_larval_lookup);
 
+int crypto_probing_notify(unsigned long val, void *v)
+{
+       int ok;
+
+       ok = blocking_notifier_call_chain(&crypto_chain, val, v);
+       if (ok == NOTIFY_DONE) {
+               request_module("cryptomgr");
+               ok = blocking_notifier_call_chain(&crypto_chain, val, v);
+       }
+
+       return ok;
+}
+EXPORT_SYMBOL_GPL(crypto_probing_notify);
+
 struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask)
 {
        struct crypto_alg *alg;
        struct crypto_alg *larval;
        int ok;
 
+       if (!(mask & CRYPTO_ALG_TESTED)) {
+               type |= CRYPTO_ALG_TESTED;
+               mask |= CRYPTO_ALG_TESTED;
+       }
+
        larval = crypto_larval_lookup(name, type, mask);
        if (IS_ERR(larval) || !crypto_is_larval(larval))
                return larval;
 
-       ok = crypto_notify(CRYPTO_MSG_ALG_REQUEST, larval);
-       if (ok == NOTIFY_DONE) {
-               request_module("cryptomgr");
-               ok = crypto_notify(CRYPTO_MSG_ALG_REQUEST, larval);
-       }
+       ok = crypto_probing_notify(CRYPTO_MSG_ALG_REQUEST, larval);
 
        if (ok == NOTIFY_STOP)
                alg = crypto_larval_wait(larval);
index 185f955fb0d7f79770b7765660bd1a9cbbcfab2e..4a7e65c4df4dc3ac6af007efa1d136e1232be053 100644 (file)
@@ -696,34 +696,5 @@ void skcipher_geniv_exit(struct crypto_tfm *tfm)
 }
 EXPORT_SYMBOL_GPL(skcipher_geniv_exit);
 
-static int __init blkcipher_module_init(void)
-{
-       int err;
-
-       err = chainiv_module_init();
-       if (err)
-               goto out;
-
-       err = eseqiv_module_init();
-       if (err)
-               goto eseqiv_err;
-
-out:
-       return err;
-
-eseqiv_err:
-       chainiv_module_exit();
-       goto out;
-}
-
-static void __exit blkcipher_module_exit(void)
-{
-       eseqiv_module_exit();
-       chainiv_module_exit();
-}
-
-module_init(blkcipher_module_init);
-module_exit(blkcipher_module_exit);
-
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Generic block chaining cipher type");
index 9affadee32879c5114afab56d4bc82428c01dcf6..7c37a497b860a27733eac07c4f7ff018c0abb4a3 100644 (file)
  */
 
 #include <crypto/internal/skcipher.h>
+#include <crypto/rng.h>
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/random.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/workqueue.h>
@@ -83,6 +83,7 @@ static int chainiv_givencrypt_first(struct skcipher_givcrypt_request *req)
 {
        struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req);
        struct chainiv_ctx *ctx = crypto_ablkcipher_ctx(geniv);
+       int err = 0;
 
        spin_lock_bh(&ctx->lock);
        if (crypto_ablkcipher_crt(geniv)->givencrypt !=
@@ -90,11 +91,15 @@ static int chainiv_givencrypt_first(struct skcipher_givcrypt_request *req)
                goto unlock;
 
        crypto_ablkcipher_crt(geniv)->givencrypt = chainiv_givencrypt;
-       get_random_bytes(ctx->iv, crypto_ablkcipher_ivsize(geniv));
+       err = crypto_rng_get_bytes(crypto_default_rng, ctx->iv,
+                                  crypto_ablkcipher_ivsize(geniv));
 
 unlock:
        spin_unlock_bh(&ctx->lock);
 
+       if (err)
+               return err;
+
        return chainiv_givencrypt(req);
 }
 
@@ -203,6 +208,7 @@ static int async_chainiv_givencrypt_first(struct skcipher_givcrypt_request *req)
 {
        struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req);
        struct async_chainiv_ctx *ctx = crypto_ablkcipher_ctx(geniv);
+       int err = 0;
 
        if (test_and_set_bit(CHAINIV_STATE_INUSE, &ctx->state))
                goto out;
@@ -212,11 +218,15 @@ static int async_chainiv_givencrypt_first(struct skcipher_givcrypt_request *req)
                goto unlock;
 
        crypto_ablkcipher_crt(geniv)->givencrypt = async_chainiv_givencrypt;
-       get_random_bytes(ctx->iv, crypto_ablkcipher_ivsize(geniv));
+       err = crypto_rng_get_bytes(crypto_default_rng, ctx->iv,
+                                  crypto_ablkcipher_ivsize(geniv));
 
 unlock:
        clear_bit(CHAINIV_STATE_INUSE, &ctx->state);
 
+       if (err)
+               return err;
+
 out:
        return async_chainiv_givencrypt(req);
 }
@@ -284,9 +294,13 @@ static struct crypto_instance *chainiv_alloc(struct rtattr **tb)
        if (IS_ERR(algt))
                return ERR_PTR(err);
 
+       err = crypto_get_default_rng();
+       if (err)
+               return ERR_PTR(err);
+
        inst = skcipher_geniv_alloc(&chainiv_tmpl, tb, 0, 0);
        if (IS_ERR(inst))
-               goto out;
+               goto put_rng;
 
        inst->alg.cra_ablkcipher.givencrypt = chainiv_givencrypt_first;
 
@@ -311,21 +325,37 @@ static struct crypto_instance *chainiv_alloc(struct rtattr **tb)
 
 out:
        return inst;
+
+put_rng:
+       crypto_put_default_rng();
+       goto out;
+}
+
+static void chainiv_free(struct crypto_instance *inst)
+{
+       skcipher_geniv_free(inst);
+       crypto_put_default_rng();
 }
 
 static struct crypto_template chainiv_tmpl = {
        .name = "chainiv",
        .alloc = chainiv_alloc,
-       .free = skcipher_geniv_free,
+       .free = chainiv_free,
        .module = THIS_MODULE,
 };
 
-int __init chainiv_module_init(void)
+static int __init chainiv_module_init(void)
 {
        return crypto_register_template(&chainiv_tmpl);
 }
 
-void chainiv_module_exit(void)
+static void chainiv_module_exit(void)
 {
        crypto_unregister_template(&chainiv_tmpl);
 }
+
+module_init(chainiv_module_init);
+module_exit(chainiv_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Chain IV Generator");
index 881d30910434831f528f5be244ab502bd984d0b6..2a342c8e52b385b34f2602b0c8dfb4d465e9b573 100644 (file)
  */
 
 #include <crypto/internal/skcipher.h>
+#include <crypto/rng.h>
 #include <crypto/scatterwalk.h>
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/module.h>
-#include <linux/random.h>
 #include <linux/scatterlist.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
@@ -163,17 +163,22 @@ static int eseqiv_givencrypt_first(struct skcipher_givcrypt_request *req)
 {
        struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req);
        struct eseqiv_ctx *ctx = crypto_ablkcipher_ctx(geniv);
+       int err = 0;
 
        spin_lock_bh(&ctx->lock);
        if (crypto_ablkcipher_crt(geniv)->givencrypt != eseqiv_givencrypt_first)
                goto unlock;
 
        crypto_ablkcipher_crt(geniv)->givencrypt = eseqiv_givencrypt;
-       get_random_bytes(ctx->salt, crypto_ablkcipher_ivsize(geniv));
+       err = crypto_rng_get_bytes(crypto_default_rng, ctx->salt,
+                                  crypto_ablkcipher_ivsize(geniv));
 
 unlock:
        spin_unlock_bh(&ctx->lock);
 
+       if (err)
+               return err;
+
        return eseqiv_givencrypt(req);
 }
 
@@ -216,9 +221,13 @@ static struct crypto_instance *eseqiv_alloc(struct rtattr **tb)
        struct crypto_instance *inst;
        int err;
 
+       err = crypto_get_default_rng();
+       if (err)
+               return ERR_PTR(err);
+
        inst = skcipher_geniv_alloc(&eseqiv_tmpl, tb, 0, 0);
        if (IS_ERR(inst))
-               goto out;
+               goto put_rng;
 
        err = -EINVAL;
        if (inst->alg.cra_ablkcipher.ivsize != inst->alg.cra_blocksize)
@@ -238,22 +247,36 @@ out:
 free_inst:
        skcipher_geniv_free(inst);
        inst = ERR_PTR(err);
+put_rng:
+       crypto_put_default_rng();
        goto out;
 }
 
+static void eseqiv_free(struct crypto_instance *inst)
+{
+       skcipher_geniv_free(inst);
+       crypto_put_default_rng();
+}
+
 static struct crypto_template eseqiv_tmpl = {
        .name = "eseqiv",
        .alloc = eseqiv_alloc,
-       .free = skcipher_geniv_free,
+       .free = eseqiv_free,
        .module = THIS_MODULE,
 };
 
-int __init eseqiv_module_init(void)
+static int __init eseqiv_module_init(void)
 {
        return crypto_register_template(&eseqiv_tmpl);
 }
 
-void __exit eseqiv_module_exit(void)
+static void __exit eseqiv_module_exit(void)
 {
        crypto_unregister_template(&eseqiv_tmpl);
 }
+
+module_init(eseqiv_module_init);
+module_exit(eseqiv_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Encrypted Sequence Number IV Generator");
diff --git a/crypto/fips.c b/crypto/fips.c
new file mode 100644 (file)
index 0000000..5539700
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * FIPS 200 support.
+ *
+ * Copyright (c) 2008 Neil Horman <nhorman@tuxdriver.com>
+ *
+ * This program 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.
+ *
+ */
+
+#include "internal.h"
+
+int fips_enabled;
+EXPORT_SYMBOL_GPL(fips_enabled);
+
+/* Process kernel command-line parameter at boot time. fips=0 or fips=1 */
+static int fips_enable(char *str)
+{
+       fips_enabled = !!simple_strtol(str, NULL, 0);
+       printk(KERN_INFO "fips mode: %s\n",
+               fips_enabled ? "enabled" : "disabled");
+       return 1;
+}
+
+__setup("fips=", fips_enable);
index 683fcb2d91f41968e946792e82d6eae3e917913c..8ef72d76092e40227000c3126688f254ffed6978 100644 (file)
 #include <linux/rwsem.h>
 #include <linux/slab.h>
 
+#ifdef CONFIG_CRYPTO_FIPS
+extern int fips_enabled;
+#else
+#define fips_enabled 0
+#endif
+
 /* Crypto notification events. */
 enum {
        CRYPTO_MSG_ALG_REQUEST,
@@ -82,7 +88,7 @@ static inline unsigned int crypto_compress_ctxsize(struct crypto_alg *alg)
 }
 
 struct crypto_alg *crypto_mod_get(struct crypto_alg *alg);
-struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type, u32 mask);
+struct crypto_alg *crypto_alg_lookup(const char *name, u32 type, u32 mask);
 struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask);
 
 int crypto_init_digest_ops(struct crypto_tfm *tfm);
@@ -94,9 +100,11 @@ void crypto_exit_digest_ops(struct crypto_tfm *tfm);
 void crypto_exit_cipher_ops(struct crypto_tfm *tfm);
 void crypto_exit_compress_ops(struct crypto_tfm *tfm);
 
+struct crypto_larval *crypto_larval_alloc(const char *name, u32 type, u32 mask);
 void crypto_larval_kill(struct crypto_alg *alg);
 struct crypto_alg *crypto_larval_lookup(const char *name, u32 type, u32 mask);
 void crypto_larval_error(const char *name, u32 type, u32 mask);
+void crypto_alg_tested(const char *name, int err);
 
 void crypto_shoot_alg(struct crypto_alg *alg);
 struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type,
@@ -107,6 +115,10 @@ int crypto_register_instance(struct crypto_template *tmpl,
 
 int crypto_register_notifier(struct notifier_block *nb);
 int crypto_unregister_notifier(struct notifier_block *nb);
+int crypto_probing_notify(unsigned long val, void *v);
+
+int __init testmgr_init(void);
+void testmgr_exit(void);
 
 static inline void crypto_alg_put(struct crypto_alg *alg)
 {
@@ -139,9 +151,9 @@ static inline int crypto_is_moribund(struct crypto_alg *alg)
        return alg->cra_flags & (CRYPTO_ALG_DEAD | CRYPTO_ALG_DYING);
 }
 
-static inline int crypto_notify(unsigned long val, void *v)
+static inline void crypto_notify(unsigned long val, void *v)
 {
-       return blocking_notifier_call_chain(&crypto_chain, val, v);
+       blocking_notifier_call_chain(&crypto_chain, val, v);
 }
 
 #endif /* _CRYPTO_INTERNAL_H */
diff --git a/crypto/krng.c b/crypto/krng.c
new file mode 100644 (file)
index 0000000..4328bb3
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * RNG implementation using standard kernel RNG.
+ *
+ * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au>
+ *
+ * This program 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
+ * any later version.
+ *
+ */
+
+#include <crypto/internal/rng.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/random.h>
+
+static int krng_get_random(struct crypto_rng *tfm, u8 *rdata, unsigned int dlen)
+{
+       get_random_bytes(rdata, dlen);
+       return 0;
+}
+
+static int krng_reset(struct crypto_rng *tfm, u8 *seed, unsigned int slen)
+{
+       return 0;
+}
+
+static struct crypto_alg krng_alg = {
+       .cra_name               = "stdrng",
+       .cra_driver_name        = "krng",
+       .cra_priority           = 200,
+       .cra_flags              = CRYPTO_ALG_TYPE_RNG,
+       .cra_ctxsize            = 0,
+       .cra_type               = &crypto_rng_type,
+       .cra_module             = THIS_MODULE,
+       .cra_list               = LIST_HEAD_INIT(krng_alg.cra_list),
+       .cra_u                  = {
+               .rng = {
+                       .rng_make_random        = krng_get_random,
+                       .rng_reset              = krng_reset,
+                       .seedsize               = 0,
+               }
+       }
+};
+
+
+/* Module initalization */
+static int __init krng_mod_init(void)
+{
+       return crypto_register_alg(&krng_alg);
+}
+
+static void __exit krng_mod_fini(void)
+{
+       crypto_unregister_alg(&krng_alg);
+       return;
+}
+
+module_init(krng_mod_init);
+module_exit(krng_mod_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Kernel Random Number Generator");
+MODULE_ALIAS("stdrng");
index 02ff5670c1583e4d454dfc37028b427e92d7d342..37a13d05636d4beaaea521d4538aa711e8bbb627 100644 (file)
 #include <linux/rwsem.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/sysctl.h>
 #include "internal.h"
 
+#ifdef CONFIG_CRYPTO_FIPS
+static struct ctl_table crypto_sysctl_table[] = {
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "fips_enabled",
+               .data           = &fips_enabled,
+               .maxlen         = sizeof(int),
+               .mode           = 0444,
+               .proc_handler   = &proc_dointvec
+       },
+       {
+               .ctl_name = 0,
+       },
+};
+
+static struct ctl_table crypto_dir_table[] = {
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "crypto",
+               .mode           = 0555,
+               .child          = crypto_sysctl_table
+       },
+       {
+               .ctl_name = 0,
+       },
+};
+
+static struct ctl_table_header *crypto_sysctls;
+
+static void crypto_proc_fips_init(void)
+{
+       crypto_sysctls = register_sysctl_table(crypto_dir_table);
+}
+
+static void crypto_proc_fips_exit(void)
+{
+       if (crypto_sysctls)
+               unregister_sysctl_table(crypto_sysctls);
+}
+#else
+#define crypto_proc_fips_init()
+#define crypto_proc_fips_exit()
+#endif
+
 static void *c_start(struct seq_file *m, loff_t *pos)
 {
        down_read(&crypto_alg_sem);
@@ -46,8 +91,11 @@ static int c_show(struct seq_file *m, void *p)
        seq_printf(m, "module       : %s\n", module_name(alg->cra_module));
        seq_printf(m, "priority     : %d\n", alg->cra_priority);
        seq_printf(m, "refcnt       : %d\n", atomic_read(&alg->cra_refcnt));
+       seq_printf(m, "selftest     : %s\n",
+                  (alg->cra_flags & CRYPTO_ALG_TESTED) ?
+                  "passed" : "unknown");
        
-       switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) {
+       switch (alg->cra_flags & (CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_LARVAL)) {
        case CRYPTO_ALG_TYPE_CIPHER:
                seq_printf(m, "type         : cipher\n");
                seq_printf(m, "blocksize    : %u\n", alg->cra_blocksize);
@@ -67,7 +115,10 @@ static int c_show(struct seq_file *m, void *p)
                seq_printf(m, "type         : compression\n");
                break;
        default:
-               if (alg->cra_type && alg->cra_type->show)
+               if (alg->cra_flags & CRYPTO_ALG_LARVAL) {
+                       seq_printf(m, "type         : larval\n");
+                       seq_printf(m, "flags        : 0x%x\n", alg->cra_flags);
+               } else if (alg->cra_type && alg->cra_type->show)
                        alg->cra_type->show(m, alg);
                else
                        seq_printf(m, "type         : unknown\n");
@@ -100,9 +151,11 @@ static const struct file_operations proc_crypto_ops = {
 void __init crypto_init_proc(void)
 {
        proc_create("crypto", 0, NULL, &proc_crypto_ops);
+       crypto_proc_fips_init();
 }
 
 void __exit crypto_exit_proc(void)
 {
+       crypto_proc_fips_exit();
        remove_proc_entry("crypto", NULL);
 }
diff --git a/crypto/rng.c b/crypto/rng.c
new file mode 100644 (file)
index 0000000..6e94bc7
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Cryptographic API.
+ *
+ * RNG operations.
+ *
+ * Copyright (c) 2008 Neil Horman <nhorman@tuxdriver.com>
+ *
+ * This program 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.
+ *
+ */
+
+#include <asm/atomic.h>
+#include <crypto/internal/rng.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/random.h>
+#include <linux/seq_file.h>
+#include <linux/string.h>
+
+static DEFINE_MUTEX(crypto_default_rng_lock);
+struct crypto_rng *crypto_default_rng;
+EXPORT_SYMBOL_GPL(crypto_default_rng);
+static int crypto_default_rng_refcnt;
+
+static int rngapi_reset(struct crypto_rng *tfm, u8 *seed, unsigned int slen)
+{
+       u8 *buf = NULL;
+       int err;
+
+       if (!seed && slen) {
+               buf = kmalloc(slen, GFP_KERNEL);
+               if (!buf)
+                       return -ENOMEM;
+
+               get_random_bytes(buf, slen);
+               seed = buf;
+       }
+
+       err = crypto_rng_alg(tfm)->rng_reset(tfm, seed, slen);
+
+       kfree(buf);
+       return err;
+}
+
+static int crypto_init_rng_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
+{
+       struct rng_alg *alg = &tfm->__crt_alg->cra_rng;
+       struct rng_tfm *ops = &tfm->crt_rng;
+
+       ops->rng_gen_random = alg->rng_make_random;
+       ops->rng_reset = rngapi_reset;
+
+       return 0;
+}
+
+static void crypto_rng_show(struct seq_file *m, struct crypto_alg *alg)
+       __attribute__ ((unused));
+static void crypto_rng_show(struct seq_file *m, struct crypto_alg *alg)
+{
+       seq_printf(m, "type         : rng\n");
+       seq_printf(m, "seedsize     : %u\n", alg->cra_rng.seedsize);
+}
+
+static unsigned int crypto_rng_ctxsize(struct crypto_alg *alg, u32 type,
+                                      u32 mask)
+{
+       return alg->cra_ctxsize;
+}
+
+const struct crypto_type crypto_rng_type = {
+       .ctxsize = crypto_rng_ctxsize,
+       .init = crypto_init_rng_ops,
+#ifdef CONFIG_PROC_FS
+       .show = crypto_rng_show,
+#endif
+};
+EXPORT_SYMBOL_GPL(crypto_rng_type);
+
+int crypto_get_default_rng(void)
+{
+       struct crypto_rng *rng;
+       int err;
+
+       mutex_lock(&crypto_default_rng_lock);
+       if (!crypto_default_rng) {
+               rng = crypto_alloc_rng("stdrng", 0, 0);
+               err = PTR_ERR(rng);
+               if (IS_ERR(rng))
+                       goto unlock;
+
+               err = crypto_rng_reset(rng, NULL, crypto_rng_seedsize(rng));
+               if (err) {
+                       crypto_free_rng(rng);
+                       goto unlock;
+               }
+
+               crypto_default_rng = rng;
+       }
+
+       crypto_default_rng_refcnt++;
+       err = 0;
+
+unlock:
+       mutex_unlock(&crypto_default_rng_lock);
+
+       return err;
+}
+EXPORT_SYMBOL_GPL(crypto_get_default_rng);
+
+void crypto_put_default_rng(void)
+{
+       mutex_lock(&crypto_default_rng_lock);
+       if (!--crypto_default_rng_refcnt) {
+               crypto_free_rng(crypto_default_rng);
+               crypto_default_rng = NULL;
+       }
+       mutex_unlock(&crypto_default_rng_lock);
+}
+EXPORT_SYMBOL_GPL(crypto_put_default_rng);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Random Number Genertor");
index b903aab3157759e0803c818b32c35a52bd39ad44..5a013a8bf87a3ceb1a61036a459d71f3520ba09e 100644 (file)
 
 #include <crypto/internal/aead.h>
 #include <crypto/internal/skcipher.h>
+#include <crypto/rng.h>
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/random.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
 
@@ -189,17 +189,22 @@ static int seqiv_givencrypt_first(struct skcipher_givcrypt_request *req)
 {
        struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req);
        struct seqiv_ctx *ctx = crypto_ablkcipher_ctx(geniv);
+       int err = 0;
 
        spin_lock_bh(&ctx->lock);
        if (crypto_ablkcipher_crt(geniv)->givencrypt != seqiv_givencrypt_first)
                goto unlock;
 
        crypto_ablkcipher_crt(geniv)->givencrypt = seqiv_givencrypt;
-       get_random_bytes(ctx->salt, crypto_ablkcipher_ivsize(geniv));
+       err = crypto_rng_get_bytes(crypto_default_rng, ctx->salt,
+                                  crypto_ablkcipher_ivsize(geniv));
 
 unlock:
        spin_unlock_bh(&ctx->lock);
 
+       if (err)
+               return err;
+
        return seqiv_givencrypt(req);
 }
 
@@ -207,17 +212,22 @@ static int seqiv_aead_givencrypt_first(struct aead_givcrypt_request *req)
 {
        struct crypto_aead *geniv = aead_givcrypt_reqtfm(req);
        struct seqiv_ctx *ctx = crypto_aead_ctx(geniv);
+       int err = 0;
 
        spin_lock_bh(&ctx->lock);
        if (crypto_aead_crt(geniv)->givencrypt != seqiv_aead_givencrypt_first)
                goto unlock;
 
        crypto_aead_crt(geniv)->givencrypt = seqiv_aead_givencrypt;
-       get_random_bytes(ctx->salt, crypto_aead_ivsize(geniv));
+       err = crypto_rng_get_bytes(crypto_default_rng, ctx->salt,
+                                  crypto_aead_ivsize(geniv));
 
 unlock:
        spin_unlock_bh(&ctx->lock);
 
+       if (err)
+               return err;
+
        return seqiv_aead_givencrypt(req);
 }
 
@@ -298,19 +308,27 @@ static struct crypto_instance *seqiv_alloc(struct rtattr **tb)
        if (IS_ERR(algt))
                return ERR_PTR(err);
 
+       err = crypto_get_default_rng();
+       if (err)
+               return ERR_PTR(err);
+
        if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & CRYPTO_ALG_TYPE_MASK)
                inst = seqiv_ablkcipher_alloc(tb);
        else
                inst = seqiv_aead_alloc(tb);
 
        if (IS_ERR(inst))
-               goto out;
+               goto put_rng;
 
        inst->alg.cra_alignmask |= __alignof__(u32) - 1;
        inst->alg.cra_ctxsize += sizeof(struct seqiv_ctx);
 
 out:
        return inst;
+
+put_rng:
+       crypto_put_default_rng();
+       goto out;
 }
 
 static void seqiv_free(struct crypto_instance *inst)
@@ -319,6 +337,7 @@ static void seqiv_free(struct crypto_instance *inst)
                skcipher_geniv_free(inst);
        else
                aead_geniv_free(inst);
+       crypto_put_default_rng();
 }
 
 static struct crypto_template seqiv_tmpl = {
index 66368022e0bf32466fa4a4e0569e9e03303b6b12..28a45a1e6f423603a563ef40c821736a88ef266b 100644 (file)
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/scatterlist.h>
 #include <linux/string.h>
-#include <linux/crypto.h>
 #include <linux/moduleparam.h>
 #include <linux/jiffies.h>
 #include <linux/timex.h>
 #include "tcrypt.h"
 
 /*
- * Need to kmalloc() memory for testing.
+ * Need slab memory for testing (size in number of pages).
  */
-#define TVMEMSIZE      16384
-#define XBUFSIZE       32768
+#define TVMEMSIZE      4
 
 /*
- * Indexes into the xbuf to simulate cross-page access.
- */
-#define IDX1           32
-#define IDX2           32400
-#define IDX3           1
-#define IDX4           8193
-#define IDX5           22222
-#define IDX6           17101
-#define IDX7           27333
-#define IDX8           3000
-
-/*
-* Used by test_cipher()
+* Used by test_cipher_speed()
 */
 #define ENCRYPT 1
 #define DECRYPT 0
 
-struct tcrypt_result {
-       struct completion completion;
-       int err;
-};
-
-static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 };
-
 /*
  * Used by test_cipher_speed()
  */
 static unsigned int sec;
 
 static int mode;
-static char *xbuf;
-static char *axbuf;
-static char *tvmem;
+static char *tvmem[TVMEMSIZE];
 
 static char *check[] = {
        "des", "md5", "des3_ede", "rot13", "sha1", "sha224", "sha256",
@@ -80,655 +56,13 @@ static char *check[] = {
        "lzo", "cts", NULL
 };
 
-static void hexdump(unsigned char *buf, unsigned int len)
-{
-       print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET,
-                       16, 1,
-                       buf, len, false);
-}
-
-static void tcrypt_complete(struct crypto_async_request *req, int err)
-{
-       struct tcrypt_result *res = req->data;
-
-       if (err == -EINPROGRESS)
-               return;
-
-       res->err = err;
-       complete(&res->completion);
-}
-
-static void test_hash(char *algo, struct hash_testvec *template,
-                     unsigned int tcount)
-{
-       unsigned int i, j, k, temp;
-       struct scatterlist sg[8];
-       char result[64];
-       struct crypto_ahash *tfm;
-       struct ahash_request *req;
-       struct tcrypt_result tresult;
-       int ret;
-       void *hash_buff;
-
-       printk("\ntesting %s\n", algo);
-
-       init_completion(&tresult.completion);
-
-       tfm = crypto_alloc_ahash(algo, 0, 0);
-       if (IS_ERR(tfm)) {
-               printk("failed to load transform for %s: %ld\n", algo,
-                      PTR_ERR(tfm));
-               return;
-       }
-
-       req = ahash_request_alloc(tfm, GFP_KERNEL);
-       if (!req) {
-               printk(KERN_ERR "failed to allocate request for %s\n", algo);
-               goto out_noreq;
-       }
-       ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
-                                  tcrypt_complete, &tresult);
-
-       for (i = 0; i < tcount; i++) {
-               printk("test %u:\n", i + 1);
-               memset(result, 0, 64);
-
-               hash_buff = kzalloc(template[i].psize, GFP_KERNEL);
-               if (!hash_buff)
-                       continue;
-
-               memcpy(hash_buff, template[i].plaintext, template[i].psize);
-               sg_init_one(&sg[0], hash_buff, template[i].psize);
-
-               if (template[i].ksize) {
-                       crypto_ahash_clear_flags(tfm, ~0);
-                       ret = crypto_ahash_setkey(tfm, template[i].key,
-                                                 template[i].ksize);
-                       if (ret) {
-                               printk("setkey() failed ret=%d\n", ret);
-                               kfree(hash_buff);
-                               goto out;
-                       }
-               }
-
-               ahash_request_set_crypt(req, sg, result, template[i].psize);
-               ret = crypto_ahash_digest(req);
-               switch (ret) {
-               case 0:
-                       break;
-               case -EINPROGRESS:
-               case -EBUSY:
-                       ret = wait_for_completion_interruptible(
-                               &tresult.completion);
-                       if (!ret && !(ret = tresult.err)) {
-                               INIT_COMPLETION(tresult.completion);
-                               break;
-                       }
-                       /* fall through */
-               default:
-                       printk("digest () failed ret=%d\n", ret);
-                       kfree(hash_buff);
-                       goto out;
-               }
-
-               hexdump(result, crypto_ahash_digestsize(tfm));
-               printk("%s\n",
-                      memcmp(result, template[i].digest,
-                             crypto_ahash_digestsize(tfm)) ?
-                      "fail" : "pass");
-               kfree(hash_buff);
-       }
-
-       printk("testing %s across pages\n", algo);
-
-       /* setup the dummy buffer first */
-       memset(xbuf, 0, XBUFSIZE);
-
-       j = 0;
-       for (i = 0; i < tcount; i++) {
-               if (template[i].np) {
-                       j++;
-                       printk("test %u:\n", j);
-                       memset(result, 0, 64);
-
-                       temp = 0;
-                       sg_init_table(sg, template[i].np);
-                       for (k = 0; k < template[i].np; k++) {
-                               memcpy(&xbuf[IDX[k]],
-                                      template[i].plaintext + temp,
-                                      template[i].tap[k]);
-                               temp += template[i].tap[k];
-                               sg_set_buf(&sg[k], &xbuf[IDX[k]],
-                                           template[i].tap[k]);
-                       }
-
-                       if (template[i].ksize) {
-                               crypto_ahash_clear_flags(tfm, ~0);
-                               ret = crypto_ahash_setkey(tfm, template[i].key,
-                                                         template[i].ksize);
-
-                               if (ret) {
-                                       printk("setkey() failed ret=%d\n", ret);
-                                       goto out;
-                               }
-                       }
-
-                       ahash_request_set_crypt(req, sg, result,
-                                               template[i].psize);
-                       ret = crypto_ahash_digest(req);
-                       switch (ret) {
-                       case 0:
-                               break;
-                       case -EINPROGRESS:
-                       case -EBUSY:
-                               ret = wait_for_completion_interruptible(
-                                       &tresult.completion);
-                               if (!ret && !(ret = tresult.err)) {
-                                       INIT_COMPLETION(tresult.completion);
-                                       break;
-                               }
-                               /* fall through */
-                       default:
-                               printk("digest () failed ret=%d\n", ret);
-                               goto out;
-                       }
-
-                       hexdump(result, crypto_ahash_digestsize(tfm));
-                       printk("%s\n",
-                              memcmp(result, template[i].digest,
-                                     crypto_ahash_digestsize(tfm)) ?
-                              "fail" : "pass");
-               }
-       }
-
-out:
-       ahash_request_free(req);
-out_noreq:
-       crypto_free_ahash(tfm);
-}
-
-static void test_aead(char *algo, int enc, struct aead_testvec *template,
-                     unsigned int tcount)
-{
-       unsigned int ret, i, j, k, n, temp;
-       char *q;
-       struct crypto_aead *tfm;
-       char *key;
-       struct aead_request *req;
-       struct scatterlist sg[8];
-       struct scatterlist asg[8];
-       const char *e;
-       struct tcrypt_result result;
-       unsigned int authsize;
-       void *input;
-       void *assoc;
-       char iv[MAX_IVLEN];
-
-       if (enc == ENCRYPT)
-               e = "encryption";
-       else
-               e = "decryption";
-
-       printk(KERN_INFO "\ntesting %s %s\n", algo, e);
-
-       init_completion(&result.completion);
-
-       tfm = crypto_alloc_aead(algo, 0, 0);
-
-       if (IS_ERR(tfm)) {
-               printk(KERN_INFO "failed to load transform for %s: %ld\n",
-                      algo, PTR_ERR(tfm));
-               return;
-       }
-
-       req = aead_request_alloc(tfm, GFP_KERNEL);
-       if (!req) {
-               printk(KERN_INFO "failed to allocate request for %s\n", algo);
-               goto out;
-       }
-
-       aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
-                                 tcrypt_complete, &result);
-
-       for (i = 0, j = 0; i < tcount; i++) {
-               if (!template[i].np) {
-                       printk(KERN_INFO "test %u (%d bit key):\n",
-                              ++j, template[i].klen * 8);
-
-                       /* some tepmplates have no input data but they will
-                        * touch input
-                        */
-                       input = kzalloc(template[i].ilen + template[i].rlen, GFP_KERNEL);
-                       if (!input)
-                               continue;
-
-                       assoc = kzalloc(template[i].alen, GFP_KERNEL);
-                       if (!assoc) {
-                               kfree(input);
-                               continue;
-                       }
-
-                       memcpy(input, template[i].input, template[i].ilen);
-                       memcpy(assoc, template[i].assoc, template[i].alen);
-                       if (template[i].iv)
-                               memcpy(iv, template[i].iv, MAX_IVLEN);
-                       else
-                               memset(iv, 0, MAX_IVLEN);
-
-                       crypto_aead_clear_flags(tfm, ~0);
-                       if (template[i].wk)
-                               crypto_aead_set_flags(
-                                       tfm, CRYPTO_TFM_REQ_WEAK_KEY);
-
-                       if (template[i].key)
-                               key = template[i].key;
-                       else
-                               key = kzalloc(template[i].klen, GFP_KERNEL);
-
-                       ret = crypto_aead_setkey(tfm, key,
-                                                template[i].klen);
-                       if (ret) {
-                               printk(KERN_INFO "setkey() failed flags=%x\n",
-                                      crypto_aead_get_flags(tfm));
-
-                               if (!template[i].fail)
-                                       goto next_one;
-                       }
-
-                       authsize = abs(template[i].rlen - template[i].ilen);
-                       ret = crypto_aead_setauthsize(tfm, authsize);
-                       if (ret) {
-                               printk(KERN_INFO
-                                      "failed to set authsize = %u\n",
-                                      authsize);
-                               goto next_one;
-                       }
-
-                       sg_init_one(&sg[0], input,
-                                   template[i].ilen + (enc ? authsize : 0));
-
-                       sg_init_one(&asg[0], assoc, template[i].alen);
-
-                       aead_request_set_crypt(req, sg, sg,
-                                              template[i].ilen, iv);
-
-                       aead_request_set_assoc(req, asg, template[i].alen);
-
-                       ret = enc ?
-                               crypto_aead_encrypt(req) :
-                               crypto_aead_decrypt(req);
-
-                       switch (ret) {
-                       case 0:
-                               break;
-                       case -EINPROGRESS:
-                       case -EBUSY:
-                               ret = wait_for_completion_interruptible(
-                                       &result.completion);
-                               if (!ret && !(ret = result.err)) {
-                                       INIT_COMPLETION(result.completion);
-                                       break;
-                               }
-                               /* fall through */
-                       default:
-                               printk(KERN_INFO "%s () failed err=%d\n",
-                                      e, -ret);
-                               goto next_one;
-                       }
-
-                       q = input;
-                       hexdump(q, template[i].rlen);
-
-                       printk(KERN_INFO "enc/dec: %s\n",
-                              memcmp(q, template[i].result,
-                                     template[i].rlen) ? "fail" : "pass");
-next_one:
-                       if (!template[i].key)
-                               kfree(key);
-                       kfree(assoc);
-                       kfree(input);
-               }
-       }
-
-       printk(KERN_INFO "\ntesting %s %s across pages (chunking)\n", algo, e);
-       memset(axbuf, 0, XBUFSIZE);
-
-       for (i = 0, j = 0; i < tcount; i++) {
-               if (template[i].np) {
-                       printk(KERN_INFO "test %u (%d bit key):\n",
-                              ++j, template[i].klen * 8);
-
-                       if (template[i].iv)
-                               memcpy(iv, template[i].iv, MAX_IVLEN);
-                       else
-                               memset(iv, 0, MAX_IVLEN);
-
-                       crypto_aead_clear_flags(tfm, ~0);
-                       if (template[i].wk)
-                               crypto_aead_set_flags(
-                                       tfm, CRYPTO_TFM_REQ_WEAK_KEY);
-                       key = template[i].key;
-
-                       ret = crypto_aead_setkey(tfm, key, template[i].klen);
-                       if (ret) {
-                               printk(KERN_INFO "setkey() failed flags=%x\n",
-                                      crypto_aead_get_flags(tfm));
-
-                               if (!template[i].fail)
-                                       goto out;
-                       }
-
-                       memset(xbuf, 0, XBUFSIZE);
-                       sg_init_table(sg, template[i].np);
-                       for (k = 0, temp = 0; k < template[i].np; k++) {
-                               memcpy(&xbuf[IDX[k]],
-                                      template[i].input + temp,
-                                      template[i].tap[k]);
-                               temp += template[i].tap[k];
-                               sg_set_buf(&sg[k], &xbuf[IDX[k]],
-                                          template[i].tap[k]);
-                       }
-
-                       authsize = abs(template[i].rlen - template[i].ilen);
-                       ret = crypto_aead_setauthsize(tfm, authsize);
-                       if (ret) {
-                               printk(KERN_INFO
-                                      "failed to set authsize = %u\n",
-                                      authsize);
-                               goto out;
-                       }
-
-                       if (enc)
-                               sg[k - 1].length += authsize;
-
-                       sg_init_table(asg, template[i].anp);
-                       for (k = 0, temp = 0; k < template[i].anp; k++) {
-                               memcpy(&axbuf[IDX[k]],
-                                      template[i].assoc + temp,
-                                      template[i].atap[k]);
-                               temp += template[i].atap[k];
-                               sg_set_buf(&asg[k], &axbuf[IDX[k]],
-                                          template[i].atap[k]);
-                       }
-
-                       aead_request_set_crypt(req, sg, sg,
-                                              template[i].ilen,
-                                              iv);
-
-                       aead_request_set_assoc(req, asg, template[i].alen);
-
-                       ret = enc ?
-                               crypto_aead_encrypt(req) :
-                               crypto_aead_decrypt(req);
-
-                       switch (ret) {
-                       case 0:
-                               break;
-                       case -EINPROGRESS:
-                       case -EBUSY:
-                               ret = wait_for_completion_interruptible(
-                                       &result.completion);
-                               if (!ret && !(ret = result.err)) {
-                                       INIT_COMPLETION(result.completion);
-                                       break;
-                               }
-                               /* fall through */
-                       default:
-                               printk(KERN_INFO "%s () failed err=%d\n",
-                                      e, -ret);
-                               goto out;
-                       }
-
-                       for (k = 0, temp = 0; k < template[i].np; k++) {
-                               printk(KERN_INFO "page %u\n", k);
-                               q = &xbuf[IDX[k]];
-
-                               n = template[i].tap[k];
-                               if (k == template[i].np - 1)
-                                       n += enc ? authsize : -authsize;
-                               hexdump(q, n);
-                               printk(KERN_INFO "%s\n",
-                                      memcmp(q, template[i].result + temp, n) ?
-                                      "fail" : "pass");
-
-                               q += n;
-                               if (k == template[i].np - 1 && !enc) {
-                                       if (memcmp(q, template[i].input +
-                                                     temp + n, authsize))
-                                               n = authsize;
-                                       else
-                                               n = 0;
-                               } else {
-                                       for (n = 0; q[n]; n++)
-                                               ;
-                               }
-                               if (n) {
-                                       printk("Result buffer corruption %u "
-                                              "bytes:\n", n);
-                                       hexdump(q, n);
-                               }
-
-                               temp += template[i].tap[k];
-                       }
-               }
-       }
-
-out:
-       crypto_free_aead(tfm);
-       aead_request_free(req);
-}
-
-static void test_cipher(char *algo, int enc,
-                       struct cipher_testvec *template, unsigned int tcount)
+static int test_cipher_jiffies(struct blkcipher_desc *desc, int enc,
+                              struct scatterlist *sg, int blen, int sec)
 {
-       unsigned int ret, i, j, k, n, temp;
-       char *q;
-       struct crypto_ablkcipher *tfm;
-       struct ablkcipher_request *req;
-       struct scatterlist sg[8];
-       const char *e;
-       struct tcrypt_result result;
-       void *data;
-       char iv[MAX_IVLEN];
-
-       if (enc == ENCRYPT)
-               e = "encryption";
-       else
-               e = "decryption";
-
-       printk("\ntesting %s %s\n", algo, e);
-
-       init_completion(&result.completion);
-       tfm = crypto_alloc_ablkcipher(algo, 0, 0);
-
-       if (IS_ERR(tfm)) {
-               printk("failed to load transform for %s: %ld\n", algo,
-                      PTR_ERR(tfm));
-               return;
-       }
-
-       req = ablkcipher_request_alloc(tfm, GFP_KERNEL);
-       if (!req) {
-               printk("failed to allocate request for %s\n", algo);
-               goto out;
-       }
-
-       ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
-                                       tcrypt_complete, &result);
-
-       j = 0;
-       for (i = 0; i < tcount; i++) {
-
-               data = kzalloc(template[i].ilen, GFP_KERNEL);
-               if (!data)
-                       continue;
-
-               memcpy(data, template[i].input, template[i].ilen);
-               if (template[i].iv)
-                       memcpy(iv, template[i].iv, MAX_IVLEN);
-               else
-                       memset(iv, 0, MAX_IVLEN);
-
-               if (!(template[i].np)) {
-                       j++;
-                       printk("test %u (%d bit key):\n",
-                       j, template[i].klen * 8);
-
-                       crypto_ablkcipher_clear_flags(tfm, ~0);
-                       if (template[i].wk)
-                               crypto_ablkcipher_set_flags(
-                                       tfm, CRYPTO_TFM_REQ_WEAK_KEY);
-
-                       ret = crypto_ablkcipher_setkey(tfm, template[i].key,
-                                                      template[i].klen);
-                       if (ret) {
-                               printk("setkey() failed flags=%x\n",
-                                      crypto_ablkcipher_get_flags(tfm));
-
-                               if (!template[i].fail) {
-                                       kfree(data);
-                                       goto out;
-                               }
-                       }
-
-                       sg_init_one(&sg[0], data, template[i].ilen);
-
-                       ablkcipher_request_set_crypt(req, sg, sg,
-                                                    template[i].ilen, iv);
-                       ret = enc ?
-                               crypto_ablkcipher_encrypt(req) :
-                               crypto_ablkcipher_decrypt(req);
-
-                       switch (ret) {
-                       case 0:
-                               break;
-                       case -EINPROGRESS:
-                       case -EBUSY:
-                               ret = wait_for_completion_interruptible(
-                                       &result.completion);
-                               if (!ret && !((ret = result.err))) {
-                                       INIT_COMPLETION(result.completion);
-                                       break;
-                               }
-                               /* fall through */
-                       default:
-                               printk("%s () failed err=%d\n", e, -ret);
-                               kfree(data);
-                               goto out;
-                       }
-
-                       q = data;
-                       hexdump(q, template[i].rlen);
-
-                       printk("%s\n",
-                              memcmp(q, template[i].result,
-                                     template[i].rlen) ? "fail" : "pass");
-               }
-               kfree(data);
-       }
-
-       printk("\ntesting %s %s across pages (chunking)\n", algo, e);
-
-       j = 0;
-       for (i = 0; i < tcount; i++) {
-
-               if (template[i].iv)
-                       memcpy(iv, template[i].iv, MAX_IVLEN);
-               else
-                       memset(iv, 0, MAX_IVLEN);
-
-               if (template[i].np) {
-                       j++;
-                       printk("test %u (%d bit key):\n",
-                       j, template[i].klen * 8);
-
-                       memset(xbuf, 0, XBUFSIZE);
-                       crypto_ablkcipher_clear_flags(tfm, ~0);
-                       if (template[i].wk)
-                               crypto_ablkcipher_set_flags(
-                                       tfm, CRYPTO_TFM_REQ_WEAK_KEY);
-
-                       ret = crypto_ablkcipher_setkey(tfm, template[i].key,
-                                                      template[i].klen);
-                       if (ret) {
-                               printk("setkey() failed flags=%x\n",
-                                               crypto_ablkcipher_get_flags(tfm));
-
-                               if (!template[i].fail)
-                                       goto out;
-                       }
-
-                       temp = 0;
-                       sg_init_table(sg, template[i].np);
-                       for (k = 0; k < template[i].np; k++) {
-                               memcpy(&xbuf[IDX[k]],
-                                               template[i].input + temp,
-                                               template[i].tap[k]);
-                               temp += template[i].tap[k];
-                               sg_set_buf(&sg[k], &xbuf[IDX[k]],
-                                               template[i].tap[k]);
-                       }
-
-                       ablkcipher_request_set_crypt(req, sg, sg,
-                                       template[i].ilen, iv);
-
-                       ret = enc ?
-                               crypto_ablkcipher_encrypt(req) :
-                               crypto_ablkcipher_decrypt(req);
-
-                       switch (ret) {
-                       case 0:
-                               break;
-                       case -EINPROGRESS:
-                       case -EBUSY:
-                               ret = wait_for_completion_interruptible(
-                                       &result.completion);
-                               if (!ret && !((ret = result.err))) {
-                                       INIT_COMPLETION(result.completion);
-                                       break;
-                               }
-                               /* fall through */
-                       default:
-                               printk("%s () failed err=%d\n", e, -ret);
-                               goto out;
-                       }
-
-                       temp = 0;
-                       for (k = 0; k < template[i].np; k++) {
-                               printk("page %u\n", k);
-                               q = &xbuf[IDX[k]];
-                               hexdump(q, template[i].tap[k]);
-                               printk("%s\n",
-                                       memcmp(q, template[i].result + temp,
-                                               template[i].tap[k]) ? "fail" :
-                                       "pass");
-
-                               for (n = 0; q[template[i].tap[k] + n]; n++)
-                                       ;
-                               if (n) {
-                                       printk("Result buffer corruption %u "
-                                              "bytes:\n", n);
-                                       hexdump(&q[template[i].tap[k]], n);
-                               }
-                               temp += template[i].tap[k];
-                       }
-               }
-       }
-out:
-       crypto_free_ablkcipher(tfm);
-       ablkcipher_request_free(req);
-}
-
-static int test_cipher_jiffies(struct blkcipher_desc *desc, int enc, char *p,
-                              int blen, int sec)
-{
-       struct scatterlist sg[1];
        unsigned long start, end;
        int bcount;
        int ret;
 
-       sg_init_one(sg, p, blen);
-
        for (start = jiffies, end = start + sec * HZ, bcount = 0;
             time_before(jiffies, end); bcount++) {
                if (enc)
@@ -745,16 +79,13 @@ static int test_cipher_jiffies(struct blkcipher_desc *desc, int enc, char *p,
        return 0;
 }
 
-static int test_cipher_cycles(struct blkcipher_desc *desc, int enc, char *p,
-                             int blen)
+static int test_cipher_cycles(struct blkcipher_desc *desc, int enc,
+                             struct scatterlist *sg, int blen)
 {
-       struct scatterlist sg[1];
        unsigned long cycles = 0;
        int ret = 0;
        int i;
 
-       sg_init_one(sg, p, blen);
-
        local_bh_disable();
        local_irq_disable();
 
@@ -799,12 +130,12 @@ out:
 
 static u32 block_sizes[] = { 16, 64, 256, 1024, 8192, 0 };
 
-static void test_cipher_speed(char *algo, int enc, unsigned int sec,
-                             struct cipher_testvec *template,
+static void test_cipher_speed(const char *algo, int enc, unsigned int sec,
+                             struct cipher_speed_template *template,
                              unsigned int tcount, u8 *keysize)
 {
        unsigned int ret, i, j, iv_len;
-       unsigned char *key, *p, iv[128];
+       const char *key, iv[128];
        struct crypto_blkcipher *tfm;
        struct blkcipher_desc desc;
        const char *e;
@@ -832,27 +163,28 @@ static void test_cipher_speed(char *algo, int enc, unsigned int sec,
 
                b_size = block_sizes;
                do {
+                       struct scatterlist sg[TVMEMSIZE];
 
-                       if ((*keysize + *b_size) > TVMEMSIZE) {
-                               printk("template (%u) too big for tvmem (%u)\n",
-                                               *keysize + *b_size, TVMEMSIZE);
+                       if ((*keysize + *b_size) > TVMEMSIZE * PAGE_SIZE) {
+                               printk("template (%u) too big for "
+                                      "tvmem (%lu)\n", *keysize + *b_size,
+                                      TVMEMSIZE * PAGE_SIZE);
                                goto out;
                        }
 
                        printk("test %u (%d bit key, %d byte blocks): ", i,
                                        *keysize * 8, *b_size);
 
-                       memset(tvmem, 0xff, *keysize + *b_size);
+                       memset(tvmem[0], 0xff, PAGE_SIZE);
 
                        /* set key, plain text and IV */
-                       key = (unsigned char *)tvmem;
+                       key = tvmem[0];
                        for (j = 0; j < tcount; j++) {
                                if (template[j].klen == *keysize) {
                                        key = template[j].key;
                                        break;
                                }
                        }
-                       p = (unsigned char *)tvmem + *keysize;
 
                        ret = crypto_blkcipher_setkey(tfm, key, *keysize);
                        if (ret) {
@@ -861,6 +193,14 @@ static void test_cipher_speed(char *algo, int enc, unsigned int sec,
                                goto out;
                        }
 
+                       sg_init_table(sg, TVMEMSIZE);
+                       sg_set_buf(sg, tvmem[0] + *keysize,
+                                  PAGE_SIZE - *keysize);
+                       for (j = 1; j < TVMEMSIZE; j++) {
+                               sg_set_buf(sg + j, tvmem[j], PAGE_SIZE);
+                               memset (tvmem[j], 0xff, PAGE_SIZE);
+                       }
+
                        iv_len = crypto_blkcipher_ivsize(tfm);
                        if (iv_len) {
                                memset(&iv, 0xff, iv_len);
@@ -868,9 +208,11 @@ static void test_cipher_speed(char *algo, int enc, unsigned int sec,
                        }
 
                        if (sec)
-                               ret = test_cipher_jiffies(&desc, enc, p, *b_size, sec);
+                               ret = test_cipher_jiffies(&desc, enc, sg,
+                                                         *b_size, sec);
                        else
-                               ret = test_cipher_cycles(&desc, enc, p, *b_size);
+                               ret = test_cipher_cycles(&desc, enc, sg,
+                                                        *b_size);
 
                        if (ret) {
                                printk("%s() failed flags=%x\n", e, desc.flags);
@@ -886,19 +228,16 @@ out:
        crypto_free_blkcipher(tfm);
 }
 
-static int test_hash_jiffies_digest(struct hash_desc *desc, char *p, int blen,
+static int test_hash_jiffies_digest(struct hash_desc *desc,
+                                   struct scatterlist *sg, int blen,
                                    char *out, int sec)
 {
-       struct scatterlist sg[1];
        unsigned long start, end;
        int bcount;
        int ret;
 
-       sg_init_table(sg, 1);
-
        for (start = jiffies, end = start + sec * HZ, bcount = 0;
             time_before(jiffies, end); bcount++) {
-               sg_set_buf(sg, p, blen);
                ret = crypto_hash_digest(desc, sg, blen, out);
                if (ret)
                        return ret;
@@ -910,18 +249,15 @@ static int test_hash_jiffies_digest(struct hash_desc *desc, char *p, int blen,
        return 0;
 }
 
-static int test_hash_jiffies(struct hash_desc *desc, char *p, int blen,
-                            int plen, char *out, int sec)
+static int test_hash_jiffies(struct hash_desc *desc, struct scatterlist *sg,
+                            int blen, int plen, char *out, int sec)
 {
-       struct scatterlist sg[1];
        unsigned long start, end;
        int bcount, pcount;
        int ret;
 
        if (plen == blen)
-               return test_hash_jiffies_digest(desc, p, blen, out, sec);
-
-       sg_init_table(sg, 1);
+               return test_hash_jiffies_digest(desc, sg, blen, out, sec);
 
        for (start = jiffies, end = start + sec * HZ, bcount = 0;
             time_before(jiffies, end); bcount++) {
@@ -929,7 +265,6 @@ static int test_hash_jiffies(struct hash_desc *desc, char *p, int blen,
                if (ret)
                        return ret;
                for (pcount = 0; pcount < blen; pcount += plen) {
-                       sg_set_buf(sg, p + pcount, plen);
                        ret = crypto_hash_update(desc, sg, plen);
                        if (ret)
                                return ret;
@@ -946,22 +281,18 @@ static int test_hash_jiffies(struct hash_desc *desc, char *p, int blen,
        return 0;
 }
 
-static int test_hash_cycles_digest(struct hash_desc *desc, char *p, int blen,
-                                  char *out)
+static int test_hash_cycles_digest(struct hash_desc *desc,
+                                  struct scatterlist *sg, int blen, char *out)
 {
-       struct scatterlist sg[1];
        unsigned long cycles = 0;
        int i;
        int ret;
 
-       sg_init_table(sg, 1);
-
        local_bh_disable();
        local_irq_disable();
 
        /* Warm-up run. */
        for (i = 0; i < 4; i++) {
-               sg_set_buf(sg, p, blen);
                ret = crypto_hash_digest(desc, sg, blen, out);
                if (ret)
                        goto out;
@@ -973,7 +304,6 @@ static int test_hash_cycles_digest(struct hash_desc *desc, char *p, int blen,
 
                start = get_cycles();
 
-               sg_set_buf(sg, p, blen);
                ret = crypto_hash_digest(desc, sg, blen, out);
                if (ret)
                        goto out;
@@ -996,18 +326,15 @@ out:
        return 0;
 }
 
-static int test_hash_cycles(struct hash_desc *desc, char *p, int blen,
-                           int plen, char *out)
+static int test_hash_cycles(struct hash_desc *desc, struct scatterlist *sg,
+                           int blen, int plen, char *out)
 {
-       struct scatterlist sg[1];
        unsigned long cycles = 0;
        int i, pcount;
        int ret;
 
        if (plen == blen)
-               return test_hash_cycles_digest(desc, p, blen, out);
-
-       sg_init_table(sg, 1);
+               return test_hash_cycles_digest(desc, sg, blen, out);
 
        local_bh_disable();
        local_irq_disable();
@@ -1018,7 +345,6 @@ static int test_hash_cycles(struct hash_desc *desc, char *p, int blen,
                if (ret)
                        goto out;
                for (pcount = 0; pcount < blen; pcount += plen) {
-                       sg_set_buf(sg, p + pcount, plen);
                        ret = crypto_hash_update(desc, sg, plen);
                        if (ret)
                                goto out;
@@ -1038,7 +364,6 @@ static int test_hash_cycles(struct hash_desc *desc, char *p, int blen,
                if (ret)
                        goto out;
                for (pcount = 0; pcount < blen; pcount += plen) {
-                       sg_set_buf(sg, p + pcount, plen);
                        ret = crypto_hash_update(desc, sg, plen);
                        if (ret)
                                goto out;
@@ -1065,9 +390,10 @@ out:
        return 0;
 }
 
-static void test_hash_speed(char *algo, unsigned int sec,
-                             struct hash_speed *speed)
+static void test_hash_speed(const char *algo, unsigned int sec,
+                           struct hash_speed *speed)
 {
+       struct scatterlist sg[TVMEMSIZE];
        struct crypto_hash *tfm;
        struct hash_desc desc;
        char output[1024];
@@ -1093,23 +419,27 @@ static void test_hash_speed(char *algo, unsigned int sec,
                goto out;
        }
 
+       sg_init_table(sg, TVMEMSIZE);
+       for (i = 0; i < TVMEMSIZE; i++) {
+               sg_set_buf(sg + i, tvmem[i], PAGE_SIZE);
+               memset(tvmem[i], 0xff, PAGE_SIZE);
+       }
+
        for (i = 0; speed[i].blen != 0; i++) {
-               if (speed[i].blen > TVMEMSIZE) {
-                       printk("template (%u) too big for tvmem (%u)\n",
-                              speed[i].blen, TVMEMSIZE);
+               if (speed[i].blen > TVMEMSIZE * PAGE_SIZE) {
+                       printk("template (%u) too big for tvmem (%lu)\n",
+                              speed[i].blen, TVMEMSIZE * PAGE_SIZE);
                        goto out;
                }
 
                printk("test%3u (%5u byte blocks,%5u bytes per update,%4u updates): ",
                       i, speed[i].blen, speed[i].plen, speed[i].blen / speed[i].plen);
 
-               memset(tvmem, 0xff, speed[i].blen);
-
                if (sec)
-                       ret = test_hash_jiffies(&desc, tvmem, speed[i].blen,
+                       ret = test_hash_jiffies(&desc, sg, speed[i].blen,
                                                speed[i].plen, output, sec);
                else
-                       ret = test_hash_cycles(&desc, tvmem, speed[i].blen,
+                       ret = test_hash_cycles(&desc, sg, speed[i].blen,
                                               speed[i].plen, output);
 
                if (ret) {
@@ -1122,73 +452,6 @@ out:
        crypto_free_hash(tfm);
 }
 
-static void test_comp(char *algo, struct comp_testvec *ctemplate,
-                      struct comp_testvec *dtemplate, int ctcount, int dtcount)
-{
-       unsigned int i;
-       char result[COMP_BUF_SIZE];
-       struct crypto_comp *tfm;
-       unsigned int tsize;
-
-       printk("\ntesting %s compression\n", algo);
-
-       tfm = crypto_alloc_comp(algo, 0, CRYPTO_ALG_ASYNC);
-       if (IS_ERR(tfm)) {
-               printk("failed to load transform for %s\n", algo);
-               return;
-       }
-
-       for (i = 0; i < ctcount; i++) {
-               int ilen, ret, dlen = COMP_BUF_SIZE;
-
-               printk("test %u:\n", i + 1);
-               memset(result, 0, sizeof (result));
-
-               ilen = ctemplate[i].inlen;
-               ret = crypto_comp_compress(tfm, ctemplate[i].input,
-                                          ilen, result, &dlen);
-               if (ret) {
-                       printk("fail: ret=%d\n", ret);
-                       continue;
-               }
-               hexdump(result, dlen);
-               printk("%s (ratio %d:%d)\n",
-                      memcmp(result, ctemplate[i].output, dlen) ? "fail" : "pass",
-                      ilen, dlen);
-       }
-
-       printk("\ntesting %s decompression\n", algo);
-
-       tsize = sizeof(struct comp_testvec);
-       tsize *= dtcount;
-       if (tsize > TVMEMSIZE) {
-               printk("template (%u) too big for tvmem (%u)\n", tsize,
-                      TVMEMSIZE);
-               goto out;
-       }
-
-       for (i = 0; i < dtcount; i++) {
-               int ilen, ret, dlen = COMP_BUF_SIZE;
-
-               printk("test %u:\n", i + 1);
-               memset(result, 0, sizeof (result));
-
-               ilen = dtemplate[i].inlen;
-               ret = crypto_comp_decompress(tfm, dtemplate[i].input,
-                                            ilen, result, &dlen);
-               if (ret) {
-                       printk("fail: ret=%d\n", ret);
-                       continue;
-               }
-               hexdump(result, dlen);
-               printk("%s (ratio %d:%d)\n",
-                      memcmp(result, dtemplate[i].output, dlen) ? "fail" : "pass",
-                      ilen, dlen);
-       }
-out:
-       crypto_free_comp(tfm);
-}
-
 static void test_available(void)
 {
        char **name = check;
@@ -1201,549 +464,237 @@ static void test_available(void)
        }
 }
 
-static void do_test(void)
+static inline int tcrypt_test(const char *alg)
 {
-       switch (mode) {
+       return alg_test(alg, alg, 0, 0);
+}
+
+static void do_test(int m)
+{
+       int i;
 
+       switch (m) {
        case 0:
-               test_hash("md5", md5_tv_template, MD5_TEST_VECTORS);
-
-               test_hash("sha1", sha1_tv_template, SHA1_TEST_VECTORS);
-
-               //DES
-               test_cipher("ecb(des)", ENCRYPT, des_enc_tv_template,
-                           DES_ENC_TEST_VECTORS);
-               test_cipher("ecb(des)", DECRYPT, des_dec_tv_template,
-                           DES_DEC_TEST_VECTORS);
-               test_cipher("cbc(des)", ENCRYPT, des_cbc_enc_tv_template,
-                           DES_CBC_ENC_TEST_VECTORS);
-               test_cipher("cbc(des)", DECRYPT, des_cbc_dec_tv_template,
-                           DES_CBC_DEC_TEST_VECTORS);
-
-               //DES3_EDE
-               test_cipher("ecb(des3_ede)", ENCRYPT, des3_ede_enc_tv_template,
-                           DES3_EDE_ENC_TEST_VECTORS);
-               test_cipher("ecb(des3_ede)", DECRYPT, des3_ede_dec_tv_template,
-                           DES3_EDE_DEC_TEST_VECTORS);
-
-               test_cipher("cbc(des3_ede)", ENCRYPT,
-                           des3_ede_cbc_enc_tv_template,
-                           DES3_EDE_CBC_ENC_TEST_VECTORS);
-
-               test_cipher("cbc(des3_ede)", DECRYPT,
-                           des3_ede_cbc_dec_tv_template,
-                           DES3_EDE_CBC_DEC_TEST_VECTORS);
-
-               test_hash("md4", md4_tv_template, MD4_TEST_VECTORS);
-
-               test_hash("sha224", sha224_tv_template, SHA224_TEST_VECTORS);
-
-               test_hash("sha256", sha256_tv_template, SHA256_TEST_VECTORS);
-
-               //BLOWFISH
-               test_cipher("ecb(blowfish)", ENCRYPT, bf_enc_tv_template,
-                           BF_ENC_TEST_VECTORS);
-               test_cipher("ecb(blowfish)", DECRYPT, bf_dec_tv_template,
-                           BF_DEC_TEST_VECTORS);
-               test_cipher("cbc(blowfish)", ENCRYPT, bf_cbc_enc_tv_template,
-                           BF_CBC_ENC_TEST_VECTORS);
-               test_cipher("cbc(blowfish)", DECRYPT, bf_cbc_dec_tv_template,
-                           BF_CBC_DEC_TEST_VECTORS);
-
-               //TWOFISH
-               test_cipher("ecb(twofish)", ENCRYPT, tf_enc_tv_template,
-                           TF_ENC_TEST_VECTORS);
-               test_cipher("ecb(twofish)", DECRYPT, tf_dec_tv_template,
-                           TF_DEC_TEST_VECTORS);
-               test_cipher("cbc(twofish)", ENCRYPT, tf_cbc_enc_tv_template,
-                           TF_CBC_ENC_TEST_VECTORS);
-               test_cipher("cbc(twofish)", DECRYPT, tf_cbc_dec_tv_template,
-                           TF_CBC_DEC_TEST_VECTORS);
-
-               //SERPENT
-               test_cipher("ecb(serpent)", ENCRYPT, serpent_enc_tv_template,
-                           SERPENT_ENC_TEST_VECTORS);
-               test_cipher("ecb(serpent)", DECRYPT, serpent_dec_tv_template,
-                           SERPENT_DEC_TEST_VECTORS);
-
-               //TNEPRES
-               test_cipher("ecb(tnepres)", ENCRYPT, tnepres_enc_tv_template,
-                           TNEPRES_ENC_TEST_VECTORS);
-               test_cipher("ecb(tnepres)", DECRYPT, tnepres_dec_tv_template,
-                           TNEPRES_DEC_TEST_VECTORS);
-
-               //AES
-               test_cipher("ecb(aes)", ENCRYPT, aes_enc_tv_template,
-                           AES_ENC_TEST_VECTORS);
-               test_cipher("ecb(aes)", DECRYPT, aes_dec_tv_template,
-                           AES_DEC_TEST_VECTORS);
-               test_cipher("cbc(aes)", ENCRYPT, aes_cbc_enc_tv_template,
-                           AES_CBC_ENC_TEST_VECTORS);
-               test_cipher("cbc(aes)", DECRYPT, aes_cbc_dec_tv_template,
-                           AES_CBC_DEC_TEST_VECTORS);
-               test_cipher("lrw(aes)", ENCRYPT, aes_lrw_enc_tv_template,
-                           AES_LRW_ENC_TEST_VECTORS);
-               test_cipher("lrw(aes)", DECRYPT, aes_lrw_dec_tv_template,
-                           AES_LRW_DEC_TEST_VECTORS);
-               test_cipher("xts(aes)", ENCRYPT, aes_xts_enc_tv_template,
-                           AES_XTS_ENC_TEST_VECTORS);
-               test_cipher("xts(aes)", DECRYPT, aes_xts_dec_tv_template,
-                           AES_XTS_DEC_TEST_VECTORS);
-               test_cipher("rfc3686(ctr(aes))", ENCRYPT, aes_ctr_enc_tv_template,
-                           AES_CTR_ENC_TEST_VECTORS);
-               test_cipher("rfc3686(ctr(aes))", DECRYPT, aes_ctr_dec_tv_template,
-                           AES_CTR_DEC_TEST_VECTORS);
-               test_aead("gcm(aes)", ENCRYPT, aes_gcm_enc_tv_template,
-                         AES_GCM_ENC_TEST_VECTORS);
-               test_aead("gcm(aes)", DECRYPT, aes_gcm_dec_tv_template,
-                         AES_GCM_DEC_TEST_VECTORS);
-               test_aead("ccm(aes)", ENCRYPT, aes_ccm_enc_tv_template,
-                         AES_CCM_ENC_TEST_VECTORS);
-               test_aead("ccm(aes)", DECRYPT, aes_ccm_dec_tv_template,
-                         AES_CCM_DEC_TEST_VECTORS);
-
-               //CAST5
-               test_cipher("ecb(cast5)", ENCRYPT, cast5_enc_tv_template,
-                           CAST5_ENC_TEST_VECTORS);
-               test_cipher("ecb(cast5)", DECRYPT, cast5_dec_tv_template,
-                           CAST5_DEC_TEST_VECTORS);
-
-               //CAST6
-               test_cipher("ecb(cast6)", ENCRYPT, cast6_enc_tv_template,
-                           CAST6_ENC_TEST_VECTORS);
-               test_cipher("ecb(cast6)", DECRYPT, cast6_dec_tv_template,
-                           CAST6_DEC_TEST_VECTORS);
-
-               //ARC4
-               test_cipher("ecb(arc4)", ENCRYPT, arc4_enc_tv_template,
-                           ARC4_ENC_TEST_VECTORS);
-               test_cipher("ecb(arc4)", DECRYPT, arc4_dec_tv_template,
-                           ARC4_DEC_TEST_VECTORS);
-
-               //TEA
-               test_cipher("ecb(tea)", ENCRYPT, tea_enc_tv_template,
-                           TEA_ENC_TEST_VECTORS);
-               test_cipher("ecb(tea)", DECRYPT, tea_dec_tv_template,
-                           TEA_DEC_TEST_VECTORS);
-
-
-               //XTEA
-               test_cipher("ecb(xtea)", ENCRYPT, xtea_enc_tv_template,
-                           XTEA_ENC_TEST_VECTORS);
-               test_cipher("ecb(xtea)", DECRYPT, xtea_dec_tv_template,
-                           XTEA_DEC_TEST_VECTORS);
-
-               //KHAZAD
-               test_cipher("ecb(khazad)", ENCRYPT, khazad_enc_tv_template,
-                           KHAZAD_ENC_TEST_VECTORS);
-               test_cipher("ecb(khazad)", DECRYPT, khazad_dec_tv_template,
-                           KHAZAD_DEC_TEST_VECTORS);
-
-               //ANUBIS
-               test_cipher("ecb(anubis)", ENCRYPT, anubis_enc_tv_template,
-                           ANUBIS_ENC_TEST_VECTORS);
-               test_cipher("ecb(anubis)", DECRYPT, anubis_dec_tv_template,
-                           ANUBIS_DEC_TEST_VECTORS);
-               test_cipher("cbc(anubis)", ENCRYPT, anubis_cbc_enc_tv_template,
-                           ANUBIS_CBC_ENC_TEST_VECTORS);
-               test_cipher("cbc(anubis)", DECRYPT, anubis_cbc_dec_tv_template,
-                           ANUBIS_CBC_ENC_TEST_VECTORS);
-
-               //XETA
-               test_cipher("ecb(xeta)", ENCRYPT, xeta_enc_tv_template,
-                           XETA_ENC_TEST_VECTORS);
-               test_cipher("ecb(xeta)", DECRYPT, xeta_dec_tv_template,
-                           XETA_DEC_TEST_VECTORS);
-
-               //FCrypt
-               test_cipher("pcbc(fcrypt)", ENCRYPT, fcrypt_pcbc_enc_tv_template,
-                           FCRYPT_ENC_TEST_VECTORS);
-               test_cipher("pcbc(fcrypt)", DECRYPT, fcrypt_pcbc_dec_tv_template,
-                           FCRYPT_DEC_TEST_VECTORS);
-
-               //CAMELLIA
-               test_cipher("ecb(camellia)", ENCRYPT,
-                           camellia_enc_tv_template,
-                           CAMELLIA_ENC_TEST_VECTORS);
-               test_cipher("ecb(camellia)", DECRYPT,
-                           camellia_dec_tv_template,
-                           CAMELLIA_DEC_TEST_VECTORS);
-               test_cipher("cbc(camellia)", ENCRYPT,
-                           camellia_cbc_enc_tv_template,
-                           CAMELLIA_CBC_ENC_TEST_VECTORS);
-               test_cipher("cbc(camellia)", DECRYPT,
-                           camellia_cbc_dec_tv_template,
-                           CAMELLIA_CBC_DEC_TEST_VECTORS);
-
-               //SEED
-               test_cipher("ecb(seed)", ENCRYPT, seed_enc_tv_template,
-                           SEED_ENC_TEST_VECTORS);
-               test_cipher("ecb(seed)", DECRYPT, seed_dec_tv_template,
-                           SEED_DEC_TEST_VECTORS);
-
-               //CTS
-               test_cipher("cts(cbc(aes))", ENCRYPT, cts_mode_enc_tv_template,
-                           CTS_MODE_ENC_TEST_VECTORS);
-               test_cipher("cts(cbc(aes))", DECRYPT, cts_mode_dec_tv_template,
-                           CTS_MODE_DEC_TEST_VECTORS);
-
-               test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS);
-               test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS);
-               test_hash("wp512", wp512_tv_template, WP512_TEST_VECTORS);
-               test_hash("wp384", wp384_tv_template, WP384_TEST_VECTORS);
-               test_hash("wp256", wp256_tv_template, WP256_TEST_VECTORS);
-               test_hash("tgr192", tgr192_tv_template, TGR192_TEST_VECTORS);
-               test_hash("tgr160", tgr160_tv_template, TGR160_TEST_VECTORS);
-               test_hash("tgr128", tgr128_tv_template, TGR128_TEST_VECTORS);
-               test_comp("deflate", deflate_comp_tv_template,
-                         deflate_decomp_tv_template, DEFLATE_COMP_TEST_VECTORS,
-                         DEFLATE_DECOMP_TEST_VECTORS);
-               test_comp("lzo", lzo_comp_tv_template, lzo_decomp_tv_template,
-                         LZO_COMP_TEST_VECTORS, LZO_DECOMP_TEST_VECTORS);
-               test_hash("crc32c", crc32c_tv_template, CRC32C_TEST_VECTORS);
-               test_hash("hmac(md5)", hmac_md5_tv_template,
-                         HMAC_MD5_TEST_VECTORS);
-               test_hash("hmac(sha1)", hmac_sha1_tv_template,
-                         HMAC_SHA1_TEST_VECTORS);
-               test_hash("hmac(sha224)", hmac_sha224_tv_template,
-                         HMAC_SHA224_TEST_VECTORS);
-               test_hash("hmac(sha256)", hmac_sha256_tv_template,
-                         HMAC_SHA256_TEST_VECTORS);
-               test_hash("hmac(sha384)", hmac_sha384_tv_template,
-                         HMAC_SHA384_TEST_VECTORS);
-               test_hash("hmac(sha512)", hmac_sha512_tv_template,
-                         HMAC_SHA512_TEST_VECTORS);
-
-               test_hash("xcbc(aes)", aes_xcbc128_tv_template,
-                         XCBC_AES_TEST_VECTORS);
-
-               test_hash("michael_mic", michael_mic_tv_template, MICHAEL_MIC_TEST_VECTORS);
+               for (i = 1; i < 200; i++)
+                       do_test(i);
                break;
 
        case 1:
-               test_hash("md5", md5_tv_template, MD5_TEST_VECTORS);
+               tcrypt_test("md5");
                break;
 
        case 2:
-               test_hash("sha1", sha1_tv_template, SHA1_TEST_VECTORS);
+               tcrypt_test("sha1");
                break;
 
        case 3:
-               test_cipher("ecb(des)", ENCRYPT, des_enc_tv_template,
-                           DES_ENC_TEST_VECTORS);
-               test_cipher("ecb(des)", DECRYPT, des_dec_tv_template,
-                           DES_DEC_TEST_VECTORS);
-               test_cipher("cbc(des)", ENCRYPT, des_cbc_enc_tv_template,
-                           DES_CBC_ENC_TEST_VECTORS);
-               test_cipher("cbc(des)", DECRYPT, des_cbc_dec_tv_template,
-                           DES_CBC_DEC_TEST_VECTORS);
+               tcrypt_test("ecb(des)");
+               tcrypt_test("cbc(des)");
                break;
 
        case 4:
-               test_cipher("ecb(des3_ede)", ENCRYPT, des3_ede_enc_tv_template,
-                           DES3_EDE_ENC_TEST_VECTORS);
-               test_cipher("ecb(des3_ede)", DECRYPT, des3_ede_dec_tv_template,
-                           DES3_EDE_DEC_TEST_VECTORS);
-
-               test_cipher("cbc(des3_ede)", ENCRYPT,
-                           des3_ede_cbc_enc_tv_template,
-                           DES3_EDE_CBC_ENC_TEST_VECTORS);
-
-               test_cipher("cbc(des3_ede)", DECRYPT,
-                           des3_ede_cbc_dec_tv_template,
-                           DES3_EDE_CBC_DEC_TEST_VECTORS);
+               tcrypt_test("ecb(des3_ede)");
+               tcrypt_test("cbc(des3_ede)");
                break;
 
        case 5:
-               test_hash("md4", md4_tv_template, MD4_TEST_VECTORS);
+               tcrypt_test("md4");
                break;
 
        case 6:
-               test_hash("sha256", sha256_tv_template, SHA256_TEST_VECTORS);
+               tcrypt_test("sha256");
                break;
 
        case 7:
-               test_cipher("ecb(blowfish)", ENCRYPT, bf_enc_tv_template,
-                           BF_ENC_TEST_VECTORS);
-               test_cipher("ecb(blowfish)", DECRYPT, bf_dec_tv_template,
-                           BF_DEC_TEST_VECTORS);
-               test_cipher("cbc(blowfish)", ENCRYPT, bf_cbc_enc_tv_template,
-                           BF_CBC_ENC_TEST_VECTORS);
-               test_cipher("cbc(blowfish)", DECRYPT, bf_cbc_dec_tv_template,
-                           BF_CBC_DEC_TEST_VECTORS);
+               tcrypt_test("ecb(blowfish)");
+               tcrypt_test("cbc(blowfish)");
                break;
 
        case 8:
-               test_cipher("ecb(twofish)", ENCRYPT, tf_enc_tv_template,
-                           TF_ENC_TEST_VECTORS);
-               test_cipher("ecb(twofish)", DECRYPT, tf_dec_tv_template,
-                           TF_DEC_TEST_VECTORS);
-               test_cipher("cbc(twofish)", ENCRYPT, tf_cbc_enc_tv_template,
-                           TF_CBC_ENC_TEST_VECTORS);
-               test_cipher("cbc(twofish)", DECRYPT, tf_cbc_dec_tv_template,
-                           TF_CBC_DEC_TEST_VECTORS);
+               tcrypt_test("ecb(twofish)");
+               tcrypt_test("cbc(twofish)");
                break;
 
        case 9:
-               test_cipher("ecb(serpent)", ENCRYPT, serpent_enc_tv_template,
-                           SERPENT_ENC_TEST_VECTORS);
-               test_cipher("ecb(serpent)", DECRYPT, serpent_dec_tv_template,
-                           SERPENT_DEC_TEST_VECTORS);
+               tcrypt_test("ecb(serpent)");
                break;
 
        case 10:
-               test_cipher("ecb(aes)", ENCRYPT, aes_enc_tv_template,
-                           AES_ENC_TEST_VECTORS);
-               test_cipher("ecb(aes)", DECRYPT, aes_dec_tv_template,
-                           AES_DEC_TEST_VECTORS);
-               test_cipher("cbc(aes)", ENCRYPT, aes_cbc_enc_tv_template,
-                           AES_CBC_ENC_TEST_VECTORS);
-               test_cipher("cbc(aes)", DECRYPT, aes_cbc_dec_tv_template,
-                           AES_CBC_DEC_TEST_VECTORS);
-               test_cipher("lrw(aes)", ENCRYPT, aes_lrw_enc_tv_template,
-                           AES_LRW_ENC_TEST_VECTORS);
-               test_cipher("lrw(aes)", DECRYPT, aes_lrw_dec_tv_template,
-                           AES_LRW_DEC_TEST_VECTORS);
-               test_cipher("xts(aes)", ENCRYPT, aes_xts_enc_tv_template,
-                           AES_XTS_ENC_TEST_VECTORS);
-               test_cipher("xts(aes)", DECRYPT, aes_xts_dec_tv_template,
-                           AES_XTS_DEC_TEST_VECTORS);
-               test_cipher("rfc3686(ctr(aes))", ENCRYPT, aes_ctr_enc_tv_template,
-                           AES_CTR_ENC_TEST_VECTORS);
-               test_cipher("rfc3686(ctr(aes))", DECRYPT, aes_ctr_dec_tv_template,
-                           AES_CTR_DEC_TEST_VECTORS);
+               tcrypt_test("ecb(aes)");
+               tcrypt_test("cbc(aes)");
+               tcrypt_test("lrw(aes)");
+               tcrypt_test("xts(aes)");
+               tcrypt_test("rfc3686(ctr(aes))");
                break;
 
        case 11:
-               test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS);
+               tcrypt_test("sha384");
                break;
 
        case 12:
-               test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS);
+               tcrypt_test("sha512");
                break;
 
        case 13:
-               test_comp("deflate", deflate_comp_tv_template,
-                         deflate_decomp_tv_template, DEFLATE_COMP_TEST_VECTORS,
-                         DEFLATE_DECOMP_TEST_VECTORS);
+               tcrypt_test("deflate");
                break;
 
        case 14:
-               test_cipher("ecb(cast5)", ENCRYPT, cast5_enc_tv_template,
-                           CAST5_ENC_TEST_VECTORS);
-               test_cipher("ecb(cast5)", DECRYPT, cast5_dec_tv_template,
-                           CAST5_DEC_TEST_VECTORS);
+               tcrypt_test("ecb(cast5)");
                break;
 
        case 15:
-               test_cipher("ecb(cast6)", ENCRYPT, cast6_enc_tv_template,
-                           CAST6_ENC_TEST_VECTORS);
-               test_cipher("ecb(cast6)", DECRYPT, cast6_dec_tv_template,
-                           CAST6_DEC_TEST_VECTORS);
+               tcrypt_test("ecb(cast6)");
                break;
 
        case 16:
-               test_cipher("ecb(arc4)", ENCRYPT, arc4_enc_tv_template,
-                           ARC4_ENC_TEST_VECTORS);
-               test_cipher("ecb(arc4)", DECRYPT, arc4_dec_tv_template,
-                           ARC4_DEC_TEST_VECTORS);
+               tcrypt_test("ecb(arc4)");
                break;
 
        case 17:
-               test_hash("michael_mic", michael_mic_tv_template, MICHAEL_MIC_TEST_VECTORS);
+               tcrypt_test("michael_mic");
                break;
 
        case 18:
-               test_hash("crc32c", crc32c_tv_template, CRC32C_TEST_VECTORS);
+               tcrypt_test("crc32c");
                break;
 
        case 19:
-               test_cipher("ecb(tea)", ENCRYPT, tea_enc_tv_template,
-                           TEA_ENC_TEST_VECTORS);
-               test_cipher("ecb(tea)", DECRYPT, tea_dec_tv_template,
-                           TEA_DEC_TEST_VECTORS);
+               tcrypt_test("ecb(tea)");
                break;
 
        case 20:
-               test_cipher("ecb(xtea)", ENCRYPT, xtea_enc_tv_template,
-                           XTEA_ENC_TEST_VECTORS);
-               test_cipher("ecb(xtea)", DECRYPT, xtea_dec_tv_template,
-                           XTEA_DEC_TEST_VECTORS);
+               tcrypt_test("ecb(xtea)");
                break;
 
        case 21:
-               test_cipher("ecb(khazad)", ENCRYPT, khazad_enc_tv_template,
-                           KHAZAD_ENC_TEST_VECTORS);
-               test_cipher("ecb(khazad)", DECRYPT, khazad_dec_tv_template,
-                           KHAZAD_DEC_TEST_VECTORS);
+               tcrypt_test("ecb(khazad)");
                break;
 
        case 22:
-               test_hash("wp512", wp512_tv_template, WP512_TEST_VECTORS);
+               tcrypt_test("wp512");
                break;
 
        case 23:
-               test_hash("wp384", wp384_tv_template, WP384_TEST_VECTORS);
+               tcrypt_test("wp384");
                break;
 
        case 24:
-               test_hash("wp256", wp256_tv_template, WP256_TEST_VECTORS);
+               tcrypt_test("wp256");
                break;
 
        case 25:
-               test_cipher("ecb(tnepres)", ENCRYPT, tnepres_enc_tv_template,
-                           TNEPRES_ENC_TEST_VECTORS);
-               test_cipher("ecb(tnepres)", DECRYPT, tnepres_dec_tv_template,
-                           TNEPRES_DEC_TEST_VECTORS);
+               tcrypt_test("ecb(tnepres)");
                break;
 
        case 26:
-               test_cipher("ecb(anubis)", ENCRYPT, anubis_enc_tv_template,
-                           ANUBIS_ENC_TEST_VECTORS);
-               test_cipher("ecb(anubis)", DECRYPT, anubis_dec_tv_template,
-                           ANUBIS_DEC_TEST_VECTORS);
-               test_cipher("cbc(anubis)", ENCRYPT, anubis_cbc_enc_tv_template,
-                           ANUBIS_CBC_ENC_TEST_VECTORS);
-               test_cipher("cbc(anubis)", DECRYPT, anubis_cbc_dec_tv_template,
-                           ANUBIS_CBC_ENC_TEST_VECTORS);
+               tcrypt_test("ecb(anubis)");
+               tcrypt_test("cbc(anubis)");
                break;
 
        case 27:
-               test_hash("tgr192", tgr192_tv_template, TGR192_TEST_VECTORS);
+               tcrypt_test("tgr192");
                break;
 
        case 28:
 
-               test_hash("tgr160", tgr160_tv_template, TGR160_TEST_VECTORS);
+               tcrypt_test("tgr160");
                break;
 
        case 29:
-               test_hash("tgr128", tgr128_tv_template, TGR128_TEST_VECTORS);
+               tcrypt_test("tgr128");
                break;
 
        case 30:
-               test_cipher("ecb(xeta)", ENCRYPT, xeta_enc_tv_template,
-                           XETA_ENC_TEST_VECTORS);
-               test_cipher("ecb(xeta)", DECRYPT, xeta_dec_tv_template,
-                           XETA_DEC_TEST_VECTORS);
+               tcrypt_test("ecb(xeta)");
                break;
 
        case 31:
-               test_cipher("pcbc(fcrypt)", ENCRYPT, fcrypt_pcbc_enc_tv_template,
-                           FCRYPT_ENC_TEST_VECTORS);
-               test_cipher("pcbc(fcrypt)", DECRYPT, fcrypt_pcbc_dec_tv_template,
-                           FCRYPT_DEC_TEST_VECTORS);
+               tcrypt_test("pcbc(fcrypt)");
                break;
 
        case 32:
-               test_cipher("ecb(camellia)", ENCRYPT,
-                           camellia_enc_tv_template,
-                           CAMELLIA_ENC_TEST_VECTORS);
-               test_cipher("ecb(camellia)", DECRYPT,
-                           camellia_dec_tv_template,
-                           CAMELLIA_DEC_TEST_VECTORS);
-               test_cipher("cbc(camellia)", ENCRYPT,
-                           camellia_cbc_enc_tv_template,
-                           CAMELLIA_CBC_ENC_TEST_VECTORS);
-               test_cipher("cbc(camellia)", DECRYPT,
-                           camellia_cbc_dec_tv_template,
-                           CAMELLIA_CBC_DEC_TEST_VECTORS);
+               tcrypt_test("ecb(camellia)");
+               tcrypt_test("cbc(camellia)");
                break;
        case 33:
-               test_hash("sha224", sha224_tv_template, SHA224_TEST_VECTORS);
+               tcrypt_test("sha224");
                break;
 
        case 34:
-               test_cipher("salsa20", ENCRYPT,
-                           salsa20_stream_enc_tv_template,
-                           SALSA20_STREAM_ENC_TEST_VECTORS);
+               tcrypt_test("salsa20");
                break;
 
        case 35:
-               test_aead("gcm(aes)", ENCRYPT, aes_gcm_enc_tv_template,
-                         AES_GCM_ENC_TEST_VECTORS);
-               test_aead("gcm(aes)", DECRYPT, aes_gcm_dec_tv_template,
-                         AES_GCM_DEC_TEST_VECTORS);
+               tcrypt_test("gcm(aes)");
                break;
 
        case 36:
-               test_comp("lzo", lzo_comp_tv_template, lzo_decomp_tv_template,
-                         LZO_COMP_TEST_VECTORS, LZO_DECOMP_TEST_VECTORS);
+               tcrypt_test("lzo");
                break;
 
        case 37:
-               test_aead("ccm(aes)", ENCRYPT, aes_ccm_enc_tv_template,
-                         AES_CCM_ENC_TEST_VECTORS);
-               test_aead("ccm(aes)", DECRYPT, aes_ccm_dec_tv_template,
-                         AES_CCM_DEC_TEST_VECTORS);
+               tcrypt_test("ccm(aes)");
                break;
 
        case 38:
-               test_cipher("cts(cbc(aes))", ENCRYPT, cts_mode_enc_tv_template,
-                           CTS_MODE_ENC_TEST_VECTORS);
-               test_cipher("cts(cbc(aes))", DECRYPT, cts_mode_dec_tv_template,
-                           CTS_MODE_DEC_TEST_VECTORS);
+               tcrypt_test("cts(cbc(aes))");
                break;
 
         case 39:
-               test_hash("rmd128", rmd128_tv_template, RMD128_TEST_VECTORS);
+               tcrypt_test("rmd128");
                break;
 
         case 40:
-               test_hash("rmd160", rmd160_tv_template, RMD160_TEST_VECTORS);
+               tcrypt_test("rmd160");
                break;
 
        case 41:
-               test_hash("rmd256", rmd256_tv_template, RMD256_TEST_VECTORS);
+               tcrypt_test("rmd256");
                break;
 
        case 42:
-               test_hash("rmd320", rmd320_tv_template, RMD320_TEST_VECTORS);
+               tcrypt_test("rmd320");
+               break;
+
+       case 43:
+               tcrypt_test("ecb(seed)");
                break;
 
        case 100:
-               test_hash("hmac(md5)", hmac_md5_tv_template,
-                         HMAC_MD5_TEST_VECTORS);
+               tcrypt_test("hmac(md5)");
                break;
 
        case 101:
-               test_hash("hmac(sha1)", hmac_sha1_tv_template,
-                         HMAC_SHA1_TEST_VECTORS);
+               tcrypt_test("hmac(sha1)");
                break;
 
        case 102:
-               test_hash("hmac(sha256)", hmac_sha256_tv_template,
-                         HMAC_SHA256_TEST_VECTORS);
+               tcrypt_test("hmac(sha256)");
                break;
 
        case 103:
-               test_hash("hmac(sha384)", hmac_sha384_tv_template,
-                         HMAC_SHA384_TEST_VECTORS);
+               tcrypt_test("hmac(sha384)");
                break;
 
        case 104:
-               test_hash("hmac(sha512)", hmac_sha512_tv_template,
-                         HMAC_SHA512_TEST_VECTORS);
+               tcrypt_test("hmac(sha512)");
                break;
 
        case 105:
-               test_hash("hmac(sha224)", hmac_sha224_tv_template,
-                         HMAC_SHA224_TEST_VECTORS);
+               tcrypt_test("hmac(sha224)");
                break;
 
        case 106:
-               test_hash("xcbc(aes)", aes_xcbc128_tv_template,
-                         XCBC_AES_TEST_VECTORS);
+               tcrypt_test("xcbc(aes)");
                break;
 
        case 107:
-               test_hash("hmac(rmd128)", hmac_rmd128_tv_template,
-                         HMAC_RMD128_TEST_VECTORS);
+               tcrypt_test("hmac(rmd128)");
                break;
 
        case 108:
-               test_hash("hmac(rmd160)", hmac_rmd160_tv_template,
-                         HMAC_RMD160_TEST_VECTORS);
+               tcrypt_test("hmac(rmd160)");
                break;
 
        case 200:
@@ -1767,16 +718,16 @@ static void do_test(void)
 
        case 201:
                test_cipher_speed("ecb(des3_ede)", ENCRYPT, sec,
-                               des3_ede_enc_tv_template, DES3_EDE_ENC_TEST_VECTORS,
+                               des3_speed_template, DES3_SPEED_VECTORS,
                                speed_template_24);
                test_cipher_speed("ecb(des3_ede)", DECRYPT, sec,
-                               des3_ede_enc_tv_template, DES3_EDE_ENC_TEST_VECTORS,
+                               des3_speed_template, DES3_SPEED_VECTORS,
                                speed_template_24);
                test_cipher_speed("cbc(des3_ede)", ENCRYPT, sec,
-                               des3_ede_enc_tv_template, DES3_EDE_ENC_TEST_VECTORS,
+                               des3_speed_template, DES3_SPEED_VECTORS,
                                speed_template_24);
                test_cipher_speed("cbc(des3_ede)", DECRYPT, sec,
-                               des3_ede_enc_tv_template, DES3_EDE_ENC_TEST_VECTORS,
+                               des3_speed_template, DES3_SPEED_VECTORS,
                                speed_template_24);
                break;
 
@@ -1906,31 +857,21 @@ static void do_test(void)
        case 1000:
                test_available();
                break;
-
-       default:
-               /* useful for debugging */
-               printk("not testing anything\n");
-               break;
        }
 }
 
 static int __init tcrypt_mod_init(void)
 {
        int err = -ENOMEM;
+       int i;
 
-       tvmem = kmalloc(TVMEMSIZE, GFP_KERNEL);
-       if (tvmem == NULL)
-               return err;
-
-       xbuf = kmalloc(XBUFSIZE, GFP_KERNEL);
-       if (xbuf == NULL)
-               goto err_free_tv;
-
-       axbuf = kmalloc(XBUFSIZE, GFP_KERNEL);
-       if (axbuf == NULL)
-               goto err_free_xbuf;
+       for (i = 0; i < TVMEMSIZE; i++) {
+               tvmem[i] = (void *)__get_free_page(GFP_KERNEL);
+               if (!tvmem[i])
+                       goto err_free_tv;
+       }
 
-       do_test();
+       do_test(mode);
 
        /* We intentionaly return -EAGAIN to prevent keeping
         * the module. It does all its work from init()
@@ -1940,11 +881,9 @@ static int __init tcrypt_mod_init(void)
         */
        err = -EAGAIN;
 
-       kfree(axbuf);
- err_free_xbuf:
-       kfree(xbuf);
- err_free_tv:
-       kfree(tvmem);
+err_free_tv:
+       for (i = 0; i < TVMEMSIZE && tvmem[i]; i++)
+               free_page((unsigned long)tvmem[i]);
 
        return err;
 }
index 801e0c288862cb3fa2072416b684d959acf0424a..966bbfaf95b15346e00f25f1394ceda3ec96f5d6 100644 (file)
 #ifndef _CRYPTO_TCRYPT_H
 #define _CRYPTO_TCRYPT_H
 
-#define MAX_DIGEST_SIZE                64
-#define MAX_TAP                        8
-
-#define MAX_KEYLEN             56
-#define MAX_IVLEN              32
-
-struct hash_testvec {
-       /* only used with keyed hash algorithms */
-       char *key;
-       char *plaintext;
-       char *digest;
-       unsigned char tap[MAX_TAP];
-       unsigned char psize;
-       unsigned char np;
-       unsigned char ksize;
-};
-
-struct cipher_testvec {
-       char *key;
-       char *iv;
-       char *input;
-       char *result;
-       unsigned char tap[MAX_TAP];
-       int np;
-       unsigned char fail;
-       unsigned char wk; /* weak key flag */
-       unsigned char klen;
-       unsigned short ilen;
-       unsigned short rlen;
-};
-
-struct aead_testvec {
-       char *key;
-       char *iv;
-       char *input;
-       char *assoc;
-       char *result;
-       unsigned char tap[MAX_TAP];
-       unsigned char atap[MAX_TAP];
-       int np;
-       int anp;
-       unsigned char fail;
-       unsigned char wk; /* weak key flag */
-       unsigned char klen;
-       unsigned short ilen;
-       unsigned short alen;
-       unsigned short rlen;
+struct cipher_speed_template {
+       const char *key;
+       unsigned int klen;
 };
 
 struct hash_speed {
@@ -71,8673 +27,20 @@ struct hash_speed {
        unsigned int plen;      /* per-update length */
 };
 
-static char zeroed_string[48];
-
-/*
- * MD4 test vectors from RFC1320
- */
-#define MD4_TEST_VECTORS       7
-
-static struct hash_testvec md4_tv_template [] = {
-       {
-               .plaintext = "",
-               .digest = "\x31\xd6\xcf\xe0\xd1\x6a\xe9\x31"
-                         "\xb7\x3c\x59\xd7\xe0\xc0\x89\xc0",
-       }, {
-               .plaintext = "a",
-               .psize  = 1,
-               .digest = "\xbd\xe5\x2c\xb3\x1d\xe3\x3e\x46"
-                         "\x24\x5e\x05\xfb\xdb\xd6\xfb\x24",
-       }, {
-               .plaintext = "abc",
-               .psize  = 3,
-               .digest = "\xa4\x48\x01\x7a\xaf\x21\xd8\x52"
-                         "\x5f\xc1\x0a\xe8\x7a\xa6\x72\x9d",
-       }, {
-               .plaintext = "message digest",
-               .psize  = 14,
-               .digest = "\xd9\x13\x0a\x81\x64\x54\x9f\xe8"
-                       "\x18\x87\x48\x06\xe1\xc7\x01\x4b",
-       }, {
-               .plaintext = "abcdefghijklmnopqrstuvwxyz",
-               .psize  = 26,
-               .digest = "\xd7\x9e\x1c\x30\x8a\xa5\xbb\xcd"
-                         "\xee\xa8\xed\x63\xdf\x41\x2d\xa9",
-               .np     = 2,
-               .tap    = { 13, 13 },
-       }, {
-               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
-               .psize  = 62,
-               .digest = "\x04\x3f\x85\x82\xf2\x41\xdb\x35"
-                         "\x1c\xe6\x27\xe1\x53\xe7\xf0\xe4",
-       }, {
-               .plaintext = "123456789012345678901234567890123456789012345678901234567890123"
-                          "45678901234567890",
-               .psize  = 80,
-               .digest = "\xe3\x3b\x4d\xdc\x9c\x38\xf2\x19"
-                         "\x9c\x3e\x7b\x16\x4f\xcc\x05\x36",
-       },
-};
-
-/*
- * MD5 test vectors from RFC1321
- */
-#define MD5_TEST_VECTORS       7
-
-static struct hash_testvec md5_tv_template[] = {
-       {
-               .digest = "\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04"
-                         "\xe9\x80\x09\x98\xec\xf8\x42\x7e",
-       }, {
-               .plaintext = "a",
-               .psize  = 1,
-               .digest = "\x0c\xc1\x75\xb9\xc0\xf1\xb6\xa8"
-                         "\x31\xc3\x99\xe2\x69\x77\x26\x61",
-       }, {
-               .plaintext = "abc",
-               .psize  = 3,
-               .digest = "\x90\x01\x50\x98\x3c\xd2\x4f\xb0"
-                         "\xd6\x96\x3f\x7d\x28\xe1\x7f\x72",
-       }, {
-               .plaintext = "message digest",
-               .psize  = 14,
-               .digest = "\xf9\x6b\x69\x7d\x7c\xb7\x93\x8d"
-                         "\x52\x5a\x2f\x31\xaa\xf1\x61\xd0",
-       }, {
-               .plaintext = "abcdefghijklmnopqrstuvwxyz",
-               .psize  = 26,
-               .digest = "\xc3\xfc\xd3\xd7\x61\x92\xe4\x00"
-                         "\x7d\xfb\x49\x6c\xca\x67\xe1\x3b",
-               .np     = 2,
-               .tap    = {13, 13}
-       }, {
-               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
-               .psize  = 62,
-               .digest = "\xd1\x74\xab\x98\xd2\x77\xd9\xf5"
-                         "\xa5\x61\x1c\x2c\x9f\x41\x9d\x9f",
-       }, {
-               .plaintext = "12345678901234567890123456789012345678901234567890123456789012"
-                          "345678901234567890",
-               .psize  = 80,
-               .digest = "\x57\xed\xf4\xa2\x2b\xe3\xc9\x55"
-                         "\xac\x49\xda\x2e\x21\x07\xb6\x7a",
-       }
-
-};
-
-/*
- * RIPEMD-128 test vectors from ISO/IEC 10118-3:2004(E)
- */
-#define RMD128_TEST_VECTORS     10
-
-static struct hash_testvec rmd128_tv_template[] = {
-       {
-               .digest = "\xcd\xf2\x62\x13\xa1\x50\xdc\x3e"
-                         "\xcb\x61\x0f\x18\xf6\xb3\x8b\x46",
-       }, {
-               .plaintext = "a",
-               .psize  = 1,
-               .digest = "\x86\xbe\x7a\xfa\x33\x9d\x0f\xc7"
-                         "\xcf\xc7\x85\xe7\x2f\x57\x8d\x33",
-       }, {
-               .plaintext = "abc",
-               .psize  = 3,
-               .digest = "\xc1\x4a\x12\x19\x9c\x66\xe4\xba"
-                         "\x84\x63\x6b\x0f\x69\x14\x4c\x77",
-       }, {
-               .plaintext = "message digest",
-               .psize  = 14,
-               .digest = "\x9e\x32\x7b\x3d\x6e\x52\x30\x62"
-                         "\xaf\xc1\x13\x2d\x7d\xf9\xd1\xb8",
-       }, {
-               .plaintext = "abcdefghijklmnopqrstuvwxyz",
-               .psize  = 26,
-               .digest = "\xfd\x2a\xa6\x07\xf7\x1d\xc8\xf5"
-                         "\x10\x71\x49\x22\xb3\x71\x83\x4e",
-       }, {
-               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"
-                            "fghijklmnopqrstuvwxyz0123456789",
-               .psize  = 62,
-               .digest = "\xd1\xe9\x59\xeb\x17\x9c\x91\x1f"
-                         "\xae\xa4\x62\x4c\x60\xc5\xc7\x02",
-       }, {
-               .plaintext = "1234567890123456789012345678901234567890"
-                            "1234567890123456789012345678901234567890",
-               .psize  = 80,
-               .digest = "\x3f\x45\xef\x19\x47\x32\xc2\xdb"
-                         "\xb2\xc4\xa2\xc7\x69\x79\x5f\xa3",
-        }, {
-               .plaintext = "abcdbcdecdefdefgefghfghighij"
-                            "hijkijkljklmklmnlmnomnopnopq",
-               .psize  = 56,
-               .digest = "\xa1\xaa\x06\x89\xd0\xfa\xfa\x2d"
-                         "\xdc\x22\xe8\x8b\x49\x13\x3a\x06",
-               .np     = 2,
-               .tap    = { 28, 28 },
-       }, {
-               .plaintext = "abcdefghbcdefghicdefghijdefghijkefghijklfghi"
-                            "jklmghijklmnhijklmnoijklmnopjklmnopqklmnopqr"
-                            "lmnopqrsmnopqrstnopqrstu",
-               .psize  = 112,
-               .digest = "\xd4\xec\xc9\x13\xe1\xdf\x77\x6b"
-                         "\xf4\x8d\xe9\xd5\x5b\x1f\x25\x46",
-       }, {
-               .plaintext = "abcdbcdecdefdefgefghfghighijhijk",
-               .psize  = 32,
-               .digest = "\x13\xfc\x13\xe8\xef\xff\x34\x7d"
-                         "\xe1\x93\xff\x46\xdb\xac\xcf\xd4",
-       }
-};
-
-/*
- * RIPEMD-160 test vectors from ISO/IEC 10118-3:2004(E)
- */
-#define RMD160_TEST_VECTORS     10
-
-static struct hash_testvec rmd160_tv_template[] = {
-       {
-               .digest = "\x9c\x11\x85\xa5\xc5\xe9\xfc\x54\x61\x28"
-                         "\x08\x97\x7e\xe8\xf5\x48\xb2\x25\x8d\x31",
-       }, {
-               .plaintext = "a",
-               .psize  = 1,
-               .digest = "\x0b\xdc\x9d\x2d\x25\x6b\x3e\xe9\xda\xae"
-                         "\x34\x7b\xe6\xf4\xdc\x83\x5a\x46\x7f\xfe",
-       }, {
-               .plaintext = "abc",
-               .psize  = 3,
-               .digest = "\x8e\xb2\x08\xf7\xe0\x5d\x98\x7a\x9b\x04"
-                         "\x4a\x8e\x98\xc6\xb0\x87\xf1\x5a\x0b\xfc",
-       }, {
-               .plaintext = "message digest",
-               .psize  = 14,
-               .digest = "\x5d\x06\x89\xef\x49\xd2\xfa\xe5\x72\xb8"
-                         "\x81\xb1\x23\xa8\x5f\xfa\x21\x59\x5f\x36",
-       }, {
-               .plaintext = "abcdefghijklmnopqrstuvwxyz",
-               .psize  = 26,
-               .digest = "\xf7\x1c\x27\x10\x9c\x69\x2c\x1b\x56\xbb"
-                         "\xdc\xeb\x5b\x9d\x28\x65\xb3\x70\x8d\xbc",
-       }, {
-               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"
-                            "fghijklmnopqrstuvwxyz0123456789",
-               .psize  = 62,
-               .digest = "\xb0\xe2\x0b\x6e\x31\x16\x64\x02\x86\xed"
-                         "\x3a\x87\xa5\x71\x30\x79\xb2\x1f\x51\x89",
-       }, {
-               .plaintext = "1234567890123456789012345678901234567890"
-                            "1234567890123456789012345678901234567890",
-               .psize  = 80,
-               .digest = "\x9b\x75\x2e\x45\x57\x3d\x4b\x39\xf4\xdb"
-                         "\xd3\x32\x3c\xab\x82\xbf\x63\x32\x6b\xfb",
-        }, {
-               .plaintext = "abcdbcdecdefdefgefghfghighij"
-                            "hijkijkljklmklmnlmnomnopnopq",
-               .psize  = 56,
-               .digest = "\x12\xa0\x53\x38\x4a\x9c\x0c\x88\xe4\x05"
-                         "\xa0\x6c\x27\xdc\xf4\x9a\xda\x62\xeb\x2b",
-               .np     = 2,
-               .tap    = { 28, 28 },
-       }, {
-               .plaintext = "abcdefghbcdefghicdefghijdefghijkefghijklfghi"
-                            "jklmghijklmnhijklmnoijklmnopjklmnopqklmnopqr"
-                            "lmnopqrsmnopqrstnopqrstu",
-               .psize  = 112,
-               .digest = "\x6f\x3f\xa3\x9b\x6b\x50\x3c\x38\x4f\x91"
-                         "\x9a\x49\xa7\xaa\x5c\x2c\x08\xbd\xfb\x45",
-       }, {
-               .plaintext = "abcdbcdecdefdefgefghfghighijhijk",
-               .psize  = 32,
-               .digest = "\x94\xc2\x64\x11\x54\x04\xe6\x33\x79\x0d"
-                         "\xfc\xc8\x7b\x58\x7d\x36\x77\x06\x7d\x9f",
-       }
-};
-
-/*
- * RIPEMD-256 test vectors
- */
-#define RMD256_TEST_VECTORS     8
-
-static struct hash_testvec rmd256_tv_template[] = {
-       {
-               .digest = "\x02\xba\x4c\x4e\x5f\x8e\xcd\x18"
-                         "\x77\xfc\x52\xd6\x4d\x30\xe3\x7a"
-                         "\x2d\x97\x74\xfb\x1e\x5d\x02\x63"
-                         "\x80\xae\x01\x68\xe3\xc5\x52\x2d",
-       }, {
-               .plaintext = "a",
-               .psize  = 1,
-               .digest = "\xf9\x33\x3e\x45\xd8\x57\xf5\xd9"
-                         "\x0a\x91\xba\xb7\x0a\x1e\xba\x0c"
-                         "\xfb\x1b\xe4\xb0\x78\x3c\x9a\xcf"
-                         "\xcd\x88\x3a\x91\x34\x69\x29\x25",
-       }, {
-               .plaintext = "abc",
-               .psize  = 3,
-               .digest = "\xaf\xbd\x6e\x22\x8b\x9d\x8c\xbb"
-                         "\xce\xf5\xca\x2d\x03\xe6\xdb\xa1"
-                         "\x0a\xc0\xbc\x7d\xcb\xe4\x68\x0e"
-                         "\x1e\x42\xd2\xe9\x75\x45\x9b\x65",
-       }, {
-               .plaintext = "message digest",
-               .psize  = 14,
-               .digest = "\x87\xe9\x71\x75\x9a\x1c\xe4\x7a"
-                         "\x51\x4d\x5c\x91\x4c\x39\x2c\x90"
-                         "\x18\xc7\xc4\x6b\xc1\x44\x65\x55"
-                         "\x4a\xfc\xdf\x54\xa5\x07\x0c\x0e",
-       }, {
-               .plaintext = "abcdefghijklmnopqrstuvwxyz",
-               .psize  = 26,
-               .digest = "\x64\x9d\x30\x34\x75\x1e\xa2\x16"
-                         "\x77\x6b\xf9\xa1\x8a\xcc\x81\xbc"
-                         "\x78\x96\x11\x8a\x51\x97\x96\x87"
-                         "\x82\xdd\x1f\xd9\x7d\x8d\x51\x33",
-       }, {
-               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"
-                            "fghijklmnopqrstuvwxyz0123456789",
-               .psize  = 62,
-               .digest = "\x57\x40\xa4\x08\xac\x16\xb7\x20"
-                         "\xb8\x44\x24\xae\x93\x1c\xbb\x1f"
-                         "\xe3\x63\xd1\xd0\xbf\x40\x17\xf1"
-                         "\xa8\x9f\x7e\xa6\xde\x77\xa0\xb8",
-       }, {
-               .plaintext = "1234567890123456789012345678901234567890"
-                            "1234567890123456789012345678901234567890",
-               .psize  = 80,
-               .digest = "\x06\xfd\xcc\x7a\x40\x95\x48\xaa"
-                         "\xf9\x13\x68\xc0\x6a\x62\x75\xb5"
-                         "\x53\xe3\xf0\x99\xbf\x0e\xa4\xed"
-                         "\xfd\x67\x78\xdf\x89\xa8\x90\xdd",
-        }, {
-               .plaintext = "abcdbcdecdefdefgefghfghighij"
-                            "hijkijkljklmklmnlmnomnopnopq",
-               .psize  = 56,
-               .digest = "\x38\x43\x04\x55\x83\xaa\xc6\xc8"
-                         "\xc8\xd9\x12\x85\x73\xe7\xa9\x80"
-                         "\x9a\xfb\x2a\x0f\x34\xcc\xc3\x6e"
-                         "\xa9\xe7\x2f\x16\xf6\x36\x8e\x3f",
-               .np     = 2,
-               .tap    = { 28, 28 },
-       }
-};
-
-/*
- * RIPEMD-320 test vectors
- */
-#define RMD320_TEST_VECTORS     8
-
-static struct hash_testvec rmd320_tv_template[] = {
-       {
-               .digest = "\x22\xd6\x5d\x56\x61\x53\x6c\xdc\x75\xc1"
-                         "\xfd\xf5\xc6\xde\x7b\x41\xb9\xf2\x73\x25"
-                         "\xeb\xc6\x1e\x85\x57\x17\x7d\x70\x5a\x0e"
-                         "\xc8\x80\x15\x1c\x3a\x32\xa0\x08\x99\xb8",
-       }, {
-               .plaintext = "a",
-               .psize  = 1,
-               .digest = "\xce\x78\x85\x06\x38\xf9\x26\x58\xa5\xa5"
-                         "\x85\x09\x75\x79\x92\x6d\xda\x66\x7a\x57"
-                         "\x16\x56\x2c\xfc\xf6\xfb\xe7\x7f\x63\x54"
-                         "\x2f\x99\xb0\x47\x05\xd6\x97\x0d\xff\x5d",
-       }, {
-               .plaintext = "abc",
-               .psize  = 3,
-               .digest = "\xde\x4c\x01\xb3\x05\x4f\x89\x30\xa7\x9d"
-                         "\x09\xae\x73\x8e\x92\x30\x1e\x5a\x17\x08"
-                         "\x5b\xef\xfd\xc1\xb8\xd1\x16\x71\x3e\x74"
-                         "\xf8\x2f\xa9\x42\xd6\x4c\xdb\xc4\x68\x2d",
-       }, {
-               .plaintext = "message digest",
-               .psize  = 14,
-               .digest = "\x3a\x8e\x28\x50\x2e\xd4\x5d\x42\x2f\x68"
-                         "\x84\x4f\x9d\xd3\x16\xe7\xb9\x85\x33\xfa"
-                         "\x3f\x2a\x91\xd2\x9f\x84\xd4\x25\xc8\x8d"
-                         "\x6b\x4e\xff\x72\x7d\xf6\x6a\x7c\x01\x97",
-       }, {
-               .plaintext = "abcdefghijklmnopqrstuvwxyz",
-               .psize  = 26,
-               .digest = "\xca\xbd\xb1\x81\x0b\x92\x47\x0a\x20\x93"
-                         "\xaa\x6b\xce\x05\x95\x2c\x28\x34\x8c\xf4"
-                         "\x3f\xf6\x08\x41\x97\x51\x66\xbb\x40\xed"
-                         "\x23\x40\x04\xb8\x82\x44\x63\xe6\xb0\x09",
-       }, {
-               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"
-                            "fghijklmnopqrstuvwxyz0123456789",
-               .psize  = 62,
-               .digest = "\xed\x54\x49\x40\xc8\x6d\x67\xf2\x50\xd2"
-                         "\x32\xc3\x0b\x7b\x3e\x57\x70\xe0\xc6\x0c"
-                         "\x8c\xb9\xa4\xca\xfe\x3b\x11\x38\x8a\xf9"
-                         "\x92\x0e\x1b\x99\x23\x0b\x84\x3c\x86\xa4",
-       }, {
-               .plaintext = "1234567890123456789012345678901234567890"
-                            "1234567890123456789012345678901234567890",
-               .psize  = 80,
-               .digest = "\x55\x78\x88\xaf\x5f\x6d\x8e\xd6\x2a\xb6"
-                         "\x69\x45\xc6\xd2\xa0\xa4\x7e\xcd\x53\x41"
-                         "\xe9\x15\xeb\x8f\xea\x1d\x05\x24\x95\x5f"
-                         "\x82\x5d\xc7\x17\xe4\xa0\x08\xab\x2d\x42",
-        }, {
-               .plaintext = "abcdbcdecdefdefgefghfghighij"
-                            "hijkijkljklmklmnlmnomnopnopq",
-               .psize  = 56,
-               .digest = "\xd0\x34\xa7\x95\x0c\xf7\x22\x02\x1b\xa4"
-                         "\xb8\x4d\xf7\x69\xa5\xde\x20\x60\xe2\x59"
-                         "\xdf\x4c\x9b\xb4\xa4\x26\x8c\x0e\x93\x5b"
-                         "\xbc\x74\x70\xa9\x69\xc9\xd0\x72\xa1\xac",
-               .np     = 2,
-               .tap    = { 28, 28 },
-       }
-};
-
-/*
- * SHA1 test vectors  from from FIPS PUB 180-1
- */
-#define SHA1_TEST_VECTORS      2
-
-static struct hash_testvec sha1_tv_template[] = {
-       {
-               .plaintext = "abc",
-               .psize  = 3,
-               .digest = "\xa9\x99\x3e\x36\x47\x06\x81\x6a\xba\x3e"
-                         "\x25\x71\x78\x50\xc2\x6c\x9c\xd0\xd8\x9d",
-       }, {
-               .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
-               .psize  = 56,
-               .digest = "\x84\x98\x3e\x44\x1c\x3b\xd2\x6e\xba\xae"
-                         "\x4a\xa1\xf9\x51\x29\xe5\xe5\x46\x70\xf1",
-               .np     = 2,
-               .tap    = { 28, 28 }
-       }
-};
-
-
-/*
- * SHA224 test vectors from from FIPS PUB 180-2
- */
-#define SHA224_TEST_VECTORS     2
-
-static struct hash_testvec sha224_tv_template[] = {
-       {
-               .plaintext = "abc",
-               .psize  = 3,
-               .digest = "\x23\x09\x7D\x22\x34\x05\xD8\x22"
-                         "\x86\x42\xA4\x77\xBD\xA2\x55\xB3"
-                         "\x2A\xAD\xBC\xE4\xBD\xA0\xB3\xF7"
-                         "\xE3\x6C\x9D\xA7",
-       }, {
-               .plaintext =
-               "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
-               .psize  = 56,
-               .digest = "\x75\x38\x8B\x16\x51\x27\x76\xCC"
-                         "\x5D\xBA\x5D\xA1\xFD\x89\x01\x50"
-                         "\xB0\xC6\x45\x5C\xB4\xF5\x8B\x19"
-                         "\x52\x52\x25\x25",
-               .np     = 2,
-               .tap    = { 28, 28 }
-       }
-};
-
-/*
- * SHA256 test vectors from from NIST
- */
-#define SHA256_TEST_VECTORS    2
-
-static struct hash_testvec sha256_tv_template[] = {
-       {
-               .plaintext = "abc",
-               .psize  = 3,
-               .digest = "\xba\x78\x16\xbf\x8f\x01\xcf\xea"
-                         "\x41\x41\x40\xde\x5d\xae\x22\x23"
-                         "\xb0\x03\x61\xa3\x96\x17\x7a\x9c"
-                         "\xb4\x10\xff\x61\xf2\x00\x15\xad",
-       }, {
-               .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
-               .psize  = 56,
-               .digest = "\x24\x8d\x6a\x61\xd2\x06\x38\xb8"
-                         "\xe5\xc0\x26\x93\x0c\x3e\x60\x39"
-                         "\xa3\x3c\xe4\x59\x64\xff\x21\x67"
-                         "\xf6\xec\xed\xd4\x19\xdb\x06\xc1",
-               .np     = 2,
-               .tap    = { 28, 28 }
-       },
-};
-
-/*
- * SHA384 test vectors from from NIST and kerneli
- */
-#define SHA384_TEST_VECTORS    4
-
-static struct hash_testvec sha384_tv_template[] = {
-       {
-               .plaintext= "abc",
-               .psize  = 3,
-               .digest = "\xcb\x00\x75\x3f\x45\xa3\x5e\x8b"
-                         "\xb5\xa0\x3d\x69\x9a\xc6\x50\x07"
-                         "\x27\x2c\x32\xab\x0e\xde\xd1\x63"
-                         "\x1a\x8b\x60\x5a\x43\xff\x5b\xed"
-                         "\x80\x86\x07\x2b\xa1\xe7\xcc\x23"
-                         "\x58\xba\xec\xa1\x34\xc8\x25\xa7",
-       }, {
-               .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
-               .psize  = 56,
-               .digest = "\x33\x91\xfd\xdd\xfc\x8d\xc7\x39"
-                         "\x37\x07\xa6\x5b\x1b\x47\x09\x39"
-                         "\x7c\xf8\xb1\xd1\x62\xaf\x05\xab"
-                         "\xfe\x8f\x45\x0d\xe5\xf3\x6b\xc6"
-                         "\xb0\x45\x5a\x85\x20\xbc\x4e\x6f"
-                         "\x5f\xe9\x5b\x1f\xe3\xc8\x45\x2b",
-       }, {
-               .plaintext = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
-                          "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
-               .psize  = 112,
-               .digest = "\x09\x33\x0c\x33\xf7\x11\x47\xe8"
-                         "\x3d\x19\x2f\xc7\x82\xcd\x1b\x47"
-                         "\x53\x11\x1b\x17\x3b\x3b\x05\xd2"
-                         "\x2f\xa0\x80\x86\xe3\xb0\xf7\x12"
-                         "\xfc\xc7\xc7\x1a\x55\x7e\x2d\xb9"
-                         "\x66\xc3\xe9\xfa\x91\x74\x60\x39",
-       }, {
-               .plaintext = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd"
-                          "efghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz",
-               .psize  = 104,
-               .digest = "\x3d\x20\x89\x73\xab\x35\x08\xdb"
-                         "\xbd\x7e\x2c\x28\x62\xba\x29\x0a"
-                         "\xd3\x01\x0e\x49\x78\xc1\x98\xdc"
-                         "\x4d\x8f\xd0\x14\xe5\x82\x82\x3a"
-                         "\x89\xe1\x6f\x9b\x2a\x7b\xbc\x1a"
-                         "\xc9\x38\xe2\xd1\x99\xe8\xbe\xa4",
-               .np     = 4,
-               .tap    = { 26, 26, 26, 26 }
-       },
-};
-
-/*
- * SHA512 test vectors from from NIST and kerneli
- */
-#define SHA512_TEST_VECTORS    4
-
-static struct hash_testvec sha512_tv_template[] = {
-       {
-               .plaintext = "abc",
-               .psize  = 3,
-               .digest = "\xdd\xaf\x35\xa1\x93\x61\x7a\xba"
-                         "\xcc\x41\x73\x49\xae\x20\x41\x31"
-                         "\x12\xe6\xfa\x4e\x89\xa9\x7e\xa2"
-                         "\x0a\x9e\xee\xe6\x4b\x55\xd3\x9a"
-                         "\x21\x92\x99\x2a\x27\x4f\xc1\xa8"
-                         "\x36\xba\x3c\x23\xa3\xfe\xeb\xbd"
-                         "\x45\x4d\x44\x23\x64\x3c\xe8\x0e"
-                         "\x2a\x9a\xc9\x4f\xa5\x4c\xa4\x9f",
-       }, {
-               .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
-               .psize  = 56,
-               .digest = "\x20\x4a\x8f\xc6\xdd\xa8\x2f\x0a"
-                         "\x0c\xed\x7b\xeb\x8e\x08\xa4\x16"
-                         "\x57\xc1\x6e\xf4\x68\xb2\x28\xa8"
-                         "\x27\x9b\xe3\x31\xa7\x03\xc3\x35"
-                         "\x96\xfd\x15\xc1\x3b\x1b\x07\xf9"
-                         "\xaa\x1d\x3b\xea\x57\x78\x9c\xa0"
-                         "\x31\xad\x85\xc7\xa7\x1d\xd7\x03"
-                         "\x54\xec\x63\x12\x38\xca\x34\x45",
-       }, {
-               .plaintext = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
-                          "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
-               .psize  = 112,
-               .digest = "\x8e\x95\x9b\x75\xda\xe3\x13\xda"
-                         "\x8c\xf4\xf7\x28\x14\xfc\x14\x3f"
-                         "\x8f\x77\x79\xc6\xeb\x9f\x7f\xa1"
-                         "\x72\x99\xae\xad\xb6\x88\x90\x18"
-                         "\x50\x1d\x28\x9e\x49\x00\xf7\xe4"
-                         "\x33\x1b\x99\xde\xc4\xb5\x43\x3a"
-                         "\xc7\xd3\x29\xee\xb6\xdd\x26\x54"
-                         "\x5e\x96\xe5\x5b\x87\x4b\xe9\x09",
-       }, {
-               .plaintext = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd"
-                          "efghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz",
-               .psize  = 104,
-               .digest = "\x93\x0d\x0c\xef\xcb\x30\xff\x11"
-                         "\x33\xb6\x89\x81\x21\xf1\xcf\x3d"
-                         "\x27\x57\x8a\xfc\xaf\xe8\x67\x7c"
-                         "\x52\x57\xcf\x06\x99\x11\xf7\x5d"
-                         "\x8f\x58\x31\xb5\x6e\xbf\xda\x67"
-                         "\xb2\x78\xe6\x6d\xff\x8b\x84\xfe"
-                         "\x2b\x28\x70\xf7\x42\xa5\x80\xd8"
-                         "\xed\xb4\x19\x87\x23\x28\x50\xc9",
-               .np     = 4,
-               .tap    = { 26, 26, 26, 26 }
-       },
-};
-
-
-/*
- * WHIRLPOOL test vectors from Whirlpool package
- * by Vincent Rijmen and Paulo S. L. M. Barreto as part of the NESSIE
- * submission
- */
-#define WP512_TEST_VECTORS     8
-
-static struct hash_testvec wp512_tv_template[] = {
-       {
-               .plaintext = "",
-               .psize  = 0,
-               .digest = "\x19\xFA\x61\xD7\x55\x22\xA4\x66"
-                         "\x9B\x44\xE3\x9C\x1D\x2E\x17\x26"
-                         "\xC5\x30\x23\x21\x30\xD4\x07\xF8"
-                         "\x9A\xFE\xE0\x96\x49\x97\xF7\xA7"
-                         "\x3E\x83\xBE\x69\x8B\x28\x8F\xEB"
-                         "\xCF\x88\xE3\xE0\x3C\x4F\x07\x57"
-                         "\xEA\x89\x64\xE5\x9B\x63\xD9\x37"
-                         "\x08\xB1\x38\xCC\x42\xA6\x6E\xB3",
-
-
-       }, {
-               .plaintext = "a",
-               .psize  = 1,
-               .digest = "\x8A\xCA\x26\x02\x79\x2A\xEC\x6F"
-                         "\x11\xA6\x72\x06\x53\x1F\xB7\xD7"
-                         "\xF0\xDF\xF5\x94\x13\x14\x5E\x69"
-                         "\x73\xC4\x50\x01\xD0\x08\x7B\x42"
-                         "\xD1\x1B\xC6\x45\x41\x3A\xEF\xF6"
-                         "\x3A\x42\x39\x1A\x39\x14\x5A\x59"
-                         "\x1A\x92\x20\x0D\x56\x01\x95\xE5"
-                         "\x3B\x47\x85\x84\xFD\xAE\x23\x1A",
-       }, {
-               .plaintext = "abc",
-               .psize  = 3,
-               .digest = "\x4E\x24\x48\xA4\xC6\xF4\x86\xBB"
-                         "\x16\xB6\x56\x2C\x73\xB4\x02\x0B"
-                         "\xF3\x04\x3E\x3A\x73\x1B\xCE\x72"
-                         "\x1A\xE1\xB3\x03\xD9\x7E\x6D\x4C"
-                         "\x71\x81\xEE\xBD\xB6\xC5\x7E\x27"
-                         "\x7D\x0E\x34\x95\x71\x14\xCB\xD6"
-                         "\xC7\x97\xFC\x9D\x95\xD8\xB5\x82"
-                         "\xD2\x25\x29\x20\x76\xD4\xEE\xF5",
-       }, {
-               .plaintext = "message digest",
-               .psize  = 14,
-               .digest = "\x37\x8C\x84\xA4\x12\x6E\x2D\xC6"
-                         "\xE5\x6D\xCC\x74\x58\x37\x7A\xAC"
-                         "\x83\x8D\x00\x03\x22\x30\xF5\x3C"
-                         "\xE1\xF5\x70\x0C\x0F\xFB\x4D\x3B"
-                         "\x84\x21\x55\x76\x59\xEF\x55\xC1"
-                         "\x06\xB4\xB5\x2A\xC5\xA4\xAA\xA6"
-                         "\x92\xED\x92\x00\x52\x83\x8F\x33"
-                         "\x62\xE8\x6D\xBD\x37\xA8\x90\x3E",
-       }, {
-               .plaintext = "abcdefghijklmnopqrstuvwxyz",
-               .psize  = 26,
-               .digest = "\xF1\xD7\x54\x66\x26\x36\xFF\xE9"
-                         "\x2C\x82\xEB\xB9\x21\x2A\x48\x4A"
-                         "\x8D\x38\x63\x1E\xAD\x42\x38\xF5"
-                         "\x44\x2E\xE1\x3B\x80\x54\xE4\x1B"
-                         "\x08\xBF\x2A\x92\x51\xC3\x0B\x6A"
-                         "\x0B\x8A\xAE\x86\x17\x7A\xB4\xA6"
-                         "\xF6\x8F\x67\x3E\x72\x07\x86\x5D"
-                         "\x5D\x98\x19\xA3\xDB\xA4\xEB\x3B",
-       }, {
-               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-                          "abcdefghijklmnopqrstuvwxyz0123456789",
-               .psize  = 62,
-               .digest = "\xDC\x37\xE0\x08\xCF\x9E\xE6\x9B"
-                         "\xF1\x1F\x00\xED\x9A\xBA\x26\x90"
-                         "\x1D\xD7\xC2\x8C\xDE\xC0\x66\xCC"
-                         "\x6A\xF4\x2E\x40\xF8\x2F\x3A\x1E"
-                         "\x08\xEB\xA2\x66\x29\x12\x9D\x8F"
-                         "\xB7\xCB\x57\x21\x1B\x92\x81\xA6"
-                         "\x55\x17\xCC\x87\x9D\x7B\x96\x21"
-                         "\x42\xC6\x5F\x5A\x7A\xF0\x14\x67",
-       }, {
-               .plaintext = "1234567890123456789012345678901234567890"
-                          "1234567890123456789012345678901234567890",
-               .psize  = 80,
-               .digest = "\x46\x6E\xF1\x8B\xAB\xB0\x15\x4D"
-                         "\x25\xB9\xD3\x8A\x64\x14\xF5\xC0"
-                         "\x87\x84\x37\x2B\xCC\xB2\x04\xD6"
-                         "\x54\x9C\x4A\xFA\xDB\x60\x14\x29"
-                         "\x4D\x5B\xD8\xDF\x2A\x6C\x44\xE5"
-                         "\x38\xCD\x04\x7B\x26\x81\xA5\x1A"
-                         "\x2C\x60\x48\x1E\x88\xC5\xA2\x0B"
-                         "\x2C\x2A\x80\xCF\x3A\x9A\x08\x3B",
-       }, {
-               .plaintext = "abcdbcdecdefdefgefghfghighijhijk",
-               .psize  = 32,
-               .digest = "\x2A\x98\x7E\xA4\x0F\x91\x70\x61"
-                         "\xF5\xD6\xF0\xA0\xE4\x64\x4F\x48"
-                         "\x8A\x7A\x5A\x52\xDE\xEE\x65\x62"
-                         "\x07\xC5\x62\xF9\x88\xE9\x5C\x69"
-                         "\x16\xBD\xC8\x03\x1B\xC5\xBE\x1B"
-                         "\x7B\x94\x76\x39\xFE\x05\x0B\x56"
-                         "\x93\x9B\xAA\xA0\xAD\xFF\x9A\xE6"
-                         "\x74\x5B\x7B\x18\x1C\x3B\xE3\xFD",
-       },
-};
-
-#define WP384_TEST_VECTORS     8
-
-static struct hash_testvec wp384_tv_template[] = {
-       {
-               .plaintext = "",
-               .psize  = 0,
-               .digest = "\x19\xFA\x61\xD7\x55\x22\xA4\x66"
-                         "\x9B\x44\xE3\x9C\x1D\x2E\x17\x26"
-                         "\xC5\x30\x23\x21\x30\xD4\x07\xF8"
-                         "\x9A\xFE\xE0\x96\x49\x97\xF7\xA7"
-                         "\x3E\x83\xBE\x69\x8B\x28\x8F\xEB"
-                         "\xCF\x88\xE3\xE0\x3C\x4F\x07\x57",
-
-
-       }, {
-               .plaintext = "a",
-               .psize  = 1,
-               .digest = "\x8A\xCA\x26\x02\x79\x2A\xEC\x6F"
-                         "\x11\xA6\x72\x06\x53\x1F\xB7\xD7"
-                         "\xF0\xDF\xF5\x94\x13\x14\x5E\x69"
-                         "\x73\xC4\x50\x01\xD0\x08\x7B\x42"
-                         "\xD1\x1B\xC6\x45\x41\x3A\xEF\xF6"
-                         "\x3A\x42\x39\x1A\x39\x14\x5A\x59",
-       }, {
-               .plaintext = "abc",
-               .psize  = 3,
-               .digest = "\x4E\x24\x48\xA4\xC6\xF4\x86\xBB"
-                         "\x16\xB6\x56\x2C\x73\xB4\x02\x0B"
-                         "\xF3\x04\x3E\x3A\x73\x1B\xCE\x72"
-                         "\x1A\xE1\xB3\x03\xD9\x7E\x6D\x4C"
-                         "\x71\x81\xEE\xBD\xB6\xC5\x7E\x27"
-                         "\x7D\x0E\x34\x95\x71\x14\xCB\xD6",
-       }, {
-               .plaintext = "message digest",
-               .psize  = 14,
-               .digest = "\x37\x8C\x84\xA4\x12\x6E\x2D\xC6"
-                         "\xE5\x6D\xCC\x74\x58\x37\x7A\xAC"
-                         "\x83\x8D\x00\x03\x22\x30\xF5\x3C"
-                         "\xE1\xF5\x70\x0C\x0F\xFB\x4D\x3B"
-                         "\x84\x21\x55\x76\x59\xEF\x55\xC1"
-                         "\x06\xB4\xB5\x2A\xC5\xA4\xAA\xA6",
-       }, {
-               .plaintext = "abcdefghijklmnopqrstuvwxyz",
-               .psize  = 26,
-               .digest = "\xF1\xD7\x54\x66\x26\x36\xFF\xE9"
-                         "\x2C\x82\xEB\xB9\x21\x2A\x48\x4A"
-                         "\x8D\x38\x63\x1E\xAD\x42\x38\xF5"
-                         "\x44\x2E\xE1\x3B\x80\x54\xE4\x1B"
-                         "\x08\xBF\x2A\x92\x51\xC3\x0B\x6A"
-                         "\x0B\x8A\xAE\x86\x17\x7A\xB4\xA6",
-       }, {
-               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-                          "abcdefghijklmnopqrstuvwxyz0123456789",
-               .psize  = 62,
-               .digest = "\xDC\x37\xE0\x08\xCF\x9E\xE6\x9B"
-                         "\xF1\x1F\x00\xED\x9A\xBA\x26\x90"
-                         "\x1D\xD7\xC2\x8C\xDE\xC0\x66\xCC"
-                         "\x6A\xF4\x2E\x40\xF8\x2F\x3A\x1E"
-                         "\x08\xEB\xA2\x66\x29\x12\x9D\x8F"
-                         "\xB7\xCB\x57\x21\x1B\x92\x81\xA6",
-       }, {
-               .plaintext = "1234567890123456789012345678901234567890"
-                          "1234567890123456789012345678901234567890",
-               .psize  = 80,
-               .digest = "\x46\x6E\xF1\x8B\xAB\xB0\x15\x4D"
-                         "\x25\xB9\xD3\x8A\x64\x14\xF5\xC0"
-                         "\x87\x84\x37\x2B\xCC\xB2\x04\xD6"
-                         "\x54\x9C\x4A\xFA\xDB\x60\x14\x29"
-                         "\x4D\x5B\xD8\xDF\x2A\x6C\x44\xE5"
-                         "\x38\xCD\x04\x7B\x26\x81\xA5\x1A",
-       }, {
-               .plaintext = "abcdbcdecdefdefgefghfghighijhijk",
-               .psize  = 32,
-               .digest = "\x2A\x98\x7E\xA4\x0F\x91\x70\x61"
-                         "\xF5\xD6\xF0\xA0\xE4\x64\x4F\x48"
-                         "\x8A\x7A\x5A\x52\xDE\xEE\x65\x62"
-                         "\x07\xC5\x62\xF9\x88\xE9\x5C\x69"
-                         "\x16\xBD\xC8\x03\x1B\xC5\xBE\x1B"
-                         "\x7B\x94\x76\x39\xFE\x05\x0B\x56",
-       },
-};
-
-#define WP256_TEST_VECTORS     8
-
-static struct hash_testvec wp256_tv_template[] = {
-       {
-               .plaintext = "",
-               .psize  = 0,
-               .digest = "\x19\xFA\x61\xD7\x55\x22\xA4\x66"
-                         "\x9B\x44\xE3\x9C\x1D\x2E\x17\x26"
-                         "\xC5\x30\x23\x21\x30\xD4\x07\xF8"
-                         "\x9A\xFE\xE0\x96\x49\x97\xF7\xA7",
-
-
-       }, {
-               .plaintext = "a",
-               .psize  = 1,
-               .digest = "\x8A\xCA\x26\x02\x79\x2A\xEC\x6F"
-                         "\x11\xA6\x72\x06\x53\x1F\xB7\xD7"
-                         "\xF0\xDF\xF5\x94\x13\x14\x5E\x69"
-                         "\x73\xC4\x50\x01\xD0\x08\x7B\x42",
-       }, {
-               .plaintext = "abc",
-               .psize  = 3,
-               .digest = "\x4E\x24\x48\xA4\xC6\xF4\x86\xBB"
-                         "\x16\xB6\x56\x2C\x73\xB4\x02\x0B"
-                         "\xF3\x04\x3E\x3A\x73\x1B\xCE\x72"
-                         "\x1A\xE1\xB3\x03\xD9\x7E\x6D\x4C",
-       }, {
-               .plaintext = "message digest",
-               .psize  = 14,
-               .digest = "\x37\x8C\x84\xA4\x12\x6E\x2D\xC6"
-                         "\xE5\x6D\xCC\x74\x58\x37\x7A\xAC"
-                         "\x83\x8D\x00\x03\x22\x30\xF5\x3C"
-                         "\xE1\xF5\x70\x0C\x0F\xFB\x4D\x3B",
-       }, {
-               .plaintext = "abcdefghijklmnopqrstuvwxyz",
-               .psize  = 26,
-               .digest = "\xF1\xD7\x54\x66\x26\x36\xFF\xE9"
-                         "\x2C\x82\xEB\xB9\x21\x2A\x48\x4A"
-                         "\x8D\x38\x63\x1E\xAD\x42\x38\xF5"
-                         "\x44\x2E\xE1\x3B\x80\x54\xE4\x1B",
-       }, {
-               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-                          "abcdefghijklmnopqrstuvwxyz0123456789",
-               .psize  = 62,
-               .digest = "\xDC\x37\xE0\x08\xCF\x9E\xE6\x9B"
-                         "\xF1\x1F\x00\xED\x9A\xBA\x26\x90"
-                         "\x1D\xD7\xC2\x8C\xDE\xC0\x66\xCC"
-                         "\x6A\xF4\x2E\x40\xF8\x2F\x3A\x1E",
-       }, {
-               .plaintext = "1234567890123456789012345678901234567890"
-                          "1234567890123456789012345678901234567890",
-               .psize  = 80,
-               .digest = "\x46\x6E\xF1\x8B\xAB\xB0\x15\x4D"
-                         "\x25\xB9\xD3\x8A\x64\x14\xF5\xC0"
-                         "\x87\x84\x37\x2B\xCC\xB2\x04\xD6"
-                         "\x54\x9C\x4A\xFA\xDB\x60\x14\x29",
-       }, {
-               .plaintext = "abcdbcdecdefdefgefghfghighijhijk",
-               .psize  = 32,
-               .digest = "\x2A\x98\x7E\xA4\x0F\x91\x70\x61"
-                         "\xF5\xD6\xF0\xA0\xE4\x64\x4F\x48"
-                         "\x8A\x7A\x5A\x52\xDE\xEE\x65\x62"
-                         "\x07\xC5\x62\xF9\x88\xE9\x5C\x69",
-       },
-};
-
-/*
- * TIGER test vectors from Tiger website
- */
-#define TGR192_TEST_VECTORS    6
-
-static struct hash_testvec tgr192_tv_template[] = {
-       {
-               .plaintext = "",
-               .psize  = 0,
-               .digest = "\x24\xf0\x13\x0c\x63\xac\x93\x32"
-                         "\x16\x16\x6e\x76\xb1\xbb\x92\x5f"
-                         "\xf3\x73\xde\x2d\x49\x58\x4e\x7a",
-       }, {
-               .plaintext = "abc",
-               .psize  = 3,
-               .digest = "\xf2\x58\xc1\xe8\x84\x14\xab\x2a"
-                         "\x52\x7a\xb5\x41\xff\xc5\xb8\xbf"
-                         "\x93\x5f\x7b\x95\x1c\x13\x29\x51",
-       }, {
-               .plaintext = "Tiger",
-               .psize  = 5,
-               .digest = "\x9f\x00\xf5\x99\x07\x23\x00\xdd"
-                         "\x27\x6a\xbb\x38\xc8\xeb\x6d\xec"
-                         "\x37\x79\x0c\x11\x6f\x9d\x2b\xdf",
-       }, {
-               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
-               .psize  = 64,
-               .digest = "\x87\xfb\x2a\x90\x83\x85\x1c\xf7"
-                         "\x47\x0d\x2c\xf8\x10\xe6\xdf\x9e"
-                         "\xb5\x86\x44\x50\x34\xa5\xa3\x86",
-       }, {
-               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789",
-               .psize  = 64,
-               .digest = "\x46\x7d\xb8\x08\x63\xeb\xce\x48"
-                         "\x8d\xf1\xcd\x12\x61\x65\x5d\xe9"
-                         "\x57\x89\x65\x65\x97\x5f\x91\x97",
-       }, {
-               .plaintext = "Tiger - A Fast New Hash Function, "
-                          "by Ross Anderson and Eli Biham, "
-                          "proceedings of Fast Software Encryption 3, "
-                          "Cambridge, 1996.",
-               .psize  = 125,
-               .digest = "\x3d\x9a\xeb\x03\xd1\xbd\x1a\x63"
-                         "\x57\xb2\x77\x4d\xfd\x6d\x5b\x24"
-                         "\xdd\x68\x15\x1d\x50\x39\x74\xfc",
-       },
-};
-
-#define TGR160_TEST_VECTORS    6
-
-static struct hash_testvec tgr160_tv_template[] = {
-       {
-               .plaintext = "",
-               .psize  = 0,
-               .digest = "\x24\xf0\x13\x0c\x63\xac\x93\x32"
-                         "\x16\x16\x6e\x76\xb1\xbb\x92\x5f"
-                         "\xf3\x73\xde\x2d",
-       }, {
-               .plaintext = "abc",
-               .psize  = 3,
-               .digest = "\xf2\x58\xc1\xe8\x84\x14\xab\x2a"
-                         "\x52\x7a\xb5\x41\xff\xc5\xb8\xbf"
-                         "\x93\x5f\x7b\x95",
-       }, {
-               .plaintext = "Tiger",
-               .psize  = 5,
-               .digest = "\x9f\x00\xf5\x99\x07\x23\x00\xdd"
-                         "\x27\x6a\xbb\x38\xc8\xeb\x6d\xec"
-                         "\x37\x79\x0c\x11",
-       }, {
-               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
-               .psize  = 64,
-               .digest = "\x87\xfb\x2a\x90\x83\x85\x1c\xf7"
-                         "\x47\x0d\x2c\xf8\x10\xe6\xdf\x9e"
-                         "\xb5\x86\x44\x50",
-       }, {
-               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789",
-               .psize  = 64,
-               .digest = "\x46\x7d\xb8\x08\x63\xeb\xce\x48"
-                         "\x8d\xf1\xcd\x12\x61\x65\x5d\xe9"
-                         "\x57\x89\x65\x65",
-       }, {
-               .plaintext = "Tiger - A Fast New Hash Function, "
-                          "by Ross Anderson and Eli Biham, "
-                          "proceedings of Fast Software Encryption 3, "
-                          "Cambridge, 1996.",
-               .psize  = 125,
-               .digest = "\x3d\x9a\xeb\x03\xd1\xbd\x1a\x63"
-                         "\x57\xb2\x77\x4d\xfd\x6d\x5b\x24"
-                         "\xdd\x68\x15\x1d",
-       },
-};
-
-#define TGR128_TEST_VECTORS    6
-
-static struct hash_testvec tgr128_tv_template[] = {
-       {
-               .plaintext = "",
-               .psize  = 0,
-               .digest = "\x24\xf0\x13\x0c\x63\xac\x93\x32"
-                         "\x16\x16\x6e\x76\xb1\xbb\x92\x5f",
-       }, {
-               .plaintext = "abc",
-               .psize  = 3,
-               .digest = "\xf2\x58\xc1\xe8\x84\x14\xab\x2a"
-                         "\x52\x7a\xb5\x41\xff\xc5\xb8\xbf",
-       }, {
-               .plaintext = "Tiger",
-               .psize  = 5,
-               .digest = "\x9f\x00\xf5\x99\x07\x23\x00\xdd"
-                         "\x27\x6a\xbb\x38\xc8\xeb\x6d\xec",
-       }, {
-               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
-               .psize  = 64,
-               .digest = "\x87\xfb\x2a\x90\x83\x85\x1c\xf7"
-                         "\x47\x0d\x2c\xf8\x10\xe6\xdf\x9e",
-       }, {
-               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789",
-               .psize  = 64,
-               .digest = "\x46\x7d\xb8\x08\x63\xeb\xce\x48"
-                         "\x8d\xf1\xcd\x12\x61\x65\x5d\xe9",
-       }, {
-               .plaintext = "Tiger - A Fast New Hash Function, "
-                          "by Ross Anderson and Eli Biham, "
-                          "proceedings of Fast Software Encryption 3, "
-                          "Cambridge, 1996.",
-               .psize  = 125,
-               .digest = "\x3d\x9a\xeb\x03\xd1\xbd\x1a\x63"
-                         "\x57\xb2\x77\x4d\xfd\x6d\x5b\x24",
-       },
-};
-
-/*
- * HMAC-MD5 test vectors from RFC2202
- * (These need to be fixed to not use strlen).
- */
-#define HMAC_MD5_TEST_VECTORS  7
-
-static struct hash_testvec hmac_md5_tv_template[] =
-{
-       {
-               .key    = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
-               .ksize  = 16,
-               .plaintext = "Hi There",
-               .psize  = 8,
-               .digest = "\x92\x94\x72\x7a\x36\x38\xbb\x1c"
-                         "\x13\xf4\x8e\xf8\x15\x8b\xfc\x9d",
-       }, {
-               .key    = "Jefe",
-               .ksize  = 4,
-               .plaintext = "what do ya want for nothing?",
-               .psize  = 28,
-               .digest = "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03"
-                         "\xea\xa8\x6e\x31\x0a\x5d\xb7\x38",
-               .np     = 2,
-               .tap    = {14, 14}
-       }, {
-               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
-               .ksize  = 16,
-               .plaintext = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
-                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
-                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
-                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
-               .psize  = 50,
-               .digest = "\x56\xbe\x34\x52\x1d\x14\x4c\x88"
-                         "\xdb\xb8\xc7\x33\xf0\xe8\xb3\xf6",
-       }, {
-               .key    = "\x01\x02\x03\x04\x05\x06\x07\x08"
-                         "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
-                         "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
-               .ksize  = 25,
-               .plaintext = "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
-               .psize  = 50,
-               .digest = "\x69\x7e\xaf\x0a\xca\x3a\x3a\xea"
-                         "\x3a\x75\x16\x47\x46\xff\xaa\x79",
-       }, {
-               .key    = "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c",
-               .ksize  = 16,
-               .plaintext = "Test With Truncation",
-               .psize  = 20,
-               .digest = "\x56\x46\x1e\xf2\x34\x2e\xdc\x00"
-                         "\xf9\xba\xb9\x95\x69\x0e\xfd\x4c",
-       }, {
-               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa",
-               .ksize  = 80,
-               .plaintext = "Test Using Larger Than Block-Size Key - Hash Key First",
-               .psize  = 54,
-               .digest = "\x6b\x1a\xb7\xfe\x4b\xd7\xbf\x8f"
-                         "\x0b\x62\xe6\xce\x61\xb9\xd0\xcd",
-       }, {
-               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa",
-               .ksize  = 80,
-               .plaintext = "Test Using Larger Than Block-Size Key and Larger Than One "
-                          "Block-Size Data",
-               .psize  = 73,
-               .digest = "\x6f\x63\x0f\xad\x67\xcd\xa0\xee"
-                         "\x1f\xb1\xf5\x62\xdb\x3a\xa5\x3e",
-       },
-};
-
-/*
- * HMAC-RIPEMD128 test vectors from RFC2286
- */
-#define HMAC_RMD128_TEST_VECTORS       7
-
-static struct hash_testvec hmac_rmd128_tv_template[] = {
-       {
-               .key    = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
-               .ksize  = 16,
-               .plaintext = "Hi There",
-               .psize  = 8,
-               .digest = "\xfb\xf6\x1f\x94\x92\xaa\x4b\xbf"
-                         "\x81\xc1\x72\xe8\x4e\x07\x34\xdb",
-       }, {
-               .key    = "Jefe",
-               .ksize  = 4,
-               .plaintext = "what do ya want for nothing?",
-               .psize  = 28,
-               .digest = "\x87\x5f\x82\x88\x62\xb6\xb3\x34"
-                         "\xb4\x27\xc5\x5f\x9f\x7f\xf0\x9b",
-               .np     = 2,
-               .tap    = { 14, 14 },
-       }, {
-               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
-               .ksize  = 16,
-               .plaintext = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
-                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
-                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
-                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
-               .psize  = 50,
-               .digest = "\x09\xf0\xb2\x84\x6d\x2f\x54\x3d"
-                         "\xa3\x63\xcb\xec\x8d\x62\xa3\x8d",
-       }, {
-               .key    = "\x01\x02\x03\x04\x05\x06\x07\x08"
-                         "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
-                         "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
-               .ksize  = 25,
-               .plaintext = "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
-               .psize  = 50,
-               .digest = "\xbd\xbb\xd7\xcf\x03\xe4\x4b\x5a"
-                         "\xa6\x0a\xf8\x15\xbe\x4d\x22\x94",
-       }, {
-               .key    = "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c",
-               .ksize  = 16,
-               .plaintext = "Test With Truncation",
-               .psize  = 20,
-               .digest = "\xe7\x98\x08\xf2\x4b\x25\xfd\x03"
-                         "\x1c\x15\x5f\x0d\x55\x1d\x9a\x3a",
-       }, {
-               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa",
-               .ksize  = 80,
-               .plaintext = "Test Using Larger Than Block-Size Key - Hash Key First",
-               .psize  = 54,
-               .digest = "\xdc\x73\x29\x28\xde\x98\x10\x4a"
-                         "\x1f\x59\xd3\x73\xc1\x50\xac\xbb",
-       }, {
-               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa",
-               .ksize  = 80,
-               .plaintext = "Test Using Larger Than Block-Size Key and Larger Than One "
-                          "Block-Size Data",
-               .psize  = 73,
-               .digest = "\x5c\x6b\xec\x96\x79\x3e\x16\xd4"
-                         "\x06\x90\xc2\x37\x63\x5f\x30\xc5",
-       },
-};
-
-/*
- * HMAC-RIPEMD160 test vectors from RFC2286
- */
-#define HMAC_RMD160_TEST_VECTORS       7
-
-static struct hash_testvec hmac_rmd160_tv_template[] = {
-       {
-               .key    = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
-               .ksize  = 20,
-               .plaintext = "Hi There",
-               .psize  = 8,
-               .digest = "\x24\xcb\x4b\xd6\x7d\x20\xfc\x1a\x5d\x2e"
-                         "\xd7\x73\x2d\xcc\x39\x37\x7f\x0a\x56\x68",
-       }, {
-               .key    = "Jefe",
-               .ksize  = 4,
-               .plaintext = "what do ya want for nothing?",
-               .psize  = 28,
-               .digest = "\xdd\xa6\xc0\x21\x3a\x48\x5a\x9e\x24\xf4"
-                         "\x74\x20\x64\xa7\xf0\x33\xb4\x3c\x40\x69",
-               .np     = 2,
-               .tap    = { 14, 14 },
-       }, {
-               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
-               .ksize  = 20,
-               .plaintext = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
-                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
-                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
-                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
-               .psize  = 50,
-               .digest = "\xb0\xb1\x05\x36\x0d\xe7\x59\x96\x0a\xb4"
-                         "\xf3\x52\x98\xe1\x16\xe2\x95\xd8\xe7\xc1",
-       }, {
-               .key    = "\x01\x02\x03\x04\x05\x06\x07\x08"
-                         "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
-                         "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
-               .ksize  = 25,
-               .plaintext = "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
-               .psize  = 50,
-               .digest = "\xd5\xca\x86\x2f\x4d\x21\xd5\xe6\x10\xe1"
-                         "\x8b\x4c\xf1\xbe\xb9\x7a\x43\x65\xec\xf4",
-       }, {
-               .key    = "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c",
-               .ksize  = 20,
-               .plaintext = "Test With Truncation",
-               .psize  = 20,
-               .digest = "\x76\x19\x69\x39\x78\xf9\x1d\x90\x53\x9a"
-                         "\xe7\x86\x50\x0f\xf3\xd8\xe0\x51\x8e\x39",
-       }, {
-               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa",
-               .ksize  = 80,
-               .plaintext = "Test Using Larger Than Block-Size Key - Hash Key First",
-               .psize  = 54,
-               .digest = "\x64\x66\xca\x07\xac\x5e\xac\x29\xe1\xbd"
-                         "\x52\x3e\x5a\xda\x76\x05\xb7\x91\xfd\x8b",
-       }, {
-               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa",
-               .ksize  = 80,
-               .plaintext = "Test Using Larger Than Block-Size Key and Larger Than One "
-                          "Block-Size Data",
-               .psize  = 73,
-               .digest = "\x69\xea\x60\x79\x8d\x71\x61\x6c\xce\x5f"
-                         "\xd0\x87\x1e\x23\x75\x4c\xd7\x5d\x5a\x0a",
-       },
-};
-
-/*
- * HMAC-SHA1 test vectors from RFC2202
- */
-#define HMAC_SHA1_TEST_VECTORS 7
-
-static struct hash_testvec hmac_sha1_tv_template[] = {
-       {
-               .key    = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
-               .ksize  = 20,
-               .plaintext = "Hi There",
-               .psize  = 8,
-               .digest = "\xb6\x17\x31\x86\x55\x05\x72\x64"
-                         "\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1"
-                         "\x46\xbe",
-       }, {
-               .key    = "Jefe",
-               .ksize  = 4,
-               .plaintext = "what do ya want for nothing?",
-               .psize  = 28,
-               .digest = "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74"
-                         "\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79",
-               .np     = 2,
-               .tap    = { 14, 14 }
-       }, {
-               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
-               .ksize  = 20,
-               .plaintext = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
-                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
-                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
-                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
-               .psize  = 50,
-               .digest = "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3"
-                         "\x9a\xf4\x8a\xa1\x7b\x4f\x63\xf1\x75\xd3",
-       }, {
-               .key    = "\x01\x02\x03\x04\x05\x06\x07\x08"
-                         "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
-                         "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
-               .ksize  = 25,
-               .plaintext = "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
-               .psize  = 50,
-               .digest = "\x4c\x90\x07\xf4\x02\x62\x50\xc6\xbc\x84"
-                         "\x14\xf9\xbf\x50\xc8\x6c\x2d\x72\x35\xda",
-       }, {
-               .key    = "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c",
-               .ksize  = 20,
-               .plaintext = "Test With Truncation",
-               .psize  = 20,
-               .digest = "\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2"
-                         "\x7b\xe1\xd5\x8b\xb9\x32\x4a\x9a\x5a\x04",
-       }, {
-               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa",
-               .ksize  = 80,
-               .plaintext = "Test Using Larger Than Block-Size Key - Hash Key First",
-               .psize  = 54,
-               .digest = "\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70"
-                         "\x56\x37\xce\x8a\x3b\x55\xed\x40\x21\x12",
-       }, {
-               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa",
-               .ksize  = 80,
-               .plaintext = "Test Using Larger Than Block-Size Key and Larger Than One "
-                          "Block-Size Data",
-               .psize  = 73,
-               .digest = "\xe8\xe9\x9d\x0f\x45\x23\x7d\x78\x6d\x6b"
-                         "\xba\xa7\x96\x5c\x78\x08\xbb\xff\x1a\x91",
-       },
-};
-
-
-/*
- * SHA224 HMAC test vectors from RFC4231
- */
-#define HMAC_SHA224_TEST_VECTORS    4
-
-static struct hash_testvec hmac_sha224_tv_template[] = {
-       {
-               .key    = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
-                       "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
-                       "\x0b\x0b\x0b\x0b",
-               .ksize  = 20,
-               /*  ("Hi There") */
-               .plaintext = "\x48\x69\x20\x54\x68\x65\x72\x65",
-               .psize  = 8,
-               .digest = "\x89\x6f\xb1\x12\x8a\xbb\xdf\x19"
-                       "\x68\x32\x10\x7c\xd4\x9d\xf3\x3f"
-                       "\x47\xb4\xb1\x16\x99\x12\xba\x4f"
-                       "\x53\x68\x4b\x22",
-       }, {
-               .key    = "Jefe",
-               .ksize  = 4,
-               /* ("what do ya want for nothing?") */
-               .plaintext = "\x77\x68\x61\x74\x20\x64\x6f\x20"
-                       "\x79\x61\x20\x77\x61\x6e\x74\x20"
-                       "\x66\x6f\x72\x20\x6e\x6f\x74\x68"
-                       "\x69\x6e\x67\x3f",
-               .psize  = 28,
-               .digest = "\xa3\x0e\x01\x09\x8b\xc6\xdb\xbf"
-                       "\x45\x69\x0f\x3a\x7e\x9e\x6d\x0f"
-                       "\x8b\xbe\xa2\xa3\x9e\x61\x48\x00"
-                       "\x8f\xd0\x5e\x44",
-               .np = 4,
-               .tap    = { 7, 7, 7, 7 }
-       }, {
-               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa",
-               .ksize  = 131,
-               /* ("Test Using Larger Than Block-Size Key - Hash Key First") */
-               .plaintext = "\x54\x65\x73\x74\x20\x55\x73\x69"
-                       "\x6e\x67\x20\x4c\x61\x72\x67\x65"
-                       "\x72\x20\x54\x68\x61\x6e\x20\x42"
-                       "\x6c\x6f\x63\x6b\x2d\x53\x69\x7a"
-                       "\x65\x20\x4b\x65\x79\x20\x2d\x20"
-                       "\x48\x61\x73\x68\x20\x4b\x65\x79"
-                       "\x20\x46\x69\x72\x73\x74",
-               .psize  = 54,
-               .digest = "\x95\xe9\xa0\xdb\x96\x20\x95\xad"
-                       "\xae\xbe\x9b\x2d\x6f\x0d\xbc\xe2"
-                       "\xd4\x99\xf1\x12\xf2\xd2\xb7\x27"
-                       "\x3f\xa6\x87\x0e",
-       }, {
-               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa",
-               .ksize  = 131,
-               /* ("This is a test using a larger than block-size key and a")
-               (" larger than block-size data. The key needs to be")
-                       (" hashed before being used by the HMAC algorithm.") */
-               .plaintext = "\x54\x68\x69\x73\x20\x69\x73\x20"
-                       "\x61\x20\x74\x65\x73\x74\x20\x75"
-                       "\x73\x69\x6e\x67\x20\x61\x20\x6c"
-                       "\x61\x72\x67\x65\x72\x20\x74\x68"
-                       "\x61\x6e\x20\x62\x6c\x6f\x63\x6b"
-                       "\x2d\x73\x69\x7a\x65\x20\x6b\x65"
-                       "\x79\x20\x61\x6e\x64\x20\x61\x20"
-                       "\x6c\x61\x72\x67\x65\x72\x20\x74"
-                       "\x68\x61\x6e\x20\x62\x6c\x6f\x63"
-                       "\x6b\x2d\x73\x69\x7a\x65\x20\x64"
-                       "\x61\x74\x61\x2e\x20\x54\x68\x65"
-                       "\x20\x6b\x65\x79\x20\x6e\x65\x65"
-                       "\x64\x73\x20\x74\x6f\x20\x62\x65"
-                       "\x20\x68\x61\x73\x68\x65\x64\x20"
-                       "\x62\x65\x66\x6f\x72\x65\x20\x62"
-                       "\x65\x69\x6e\x67\x20\x75\x73\x65"
-                       "\x64\x20\x62\x79\x20\x74\x68\x65"
-                       "\x20\x48\x4d\x41\x43\x20\x61\x6c"
-                       "\x67\x6f\x72\x69\x74\x68\x6d\x2e",
-               .psize  = 152,
-               .digest = "\x3a\x85\x41\x66\xac\x5d\x9f\x02"
-                       "\x3f\x54\xd5\x17\xd0\xb3\x9d\xbd"
-                       "\x94\x67\x70\xdb\x9c\x2b\x95\xc9"
-                       "\xf6\xf5\x65\xd1",
-       },
-};
-
-/*
- * HMAC-SHA256 test vectors from
- * draft-ietf-ipsec-ciph-sha-256-01.txt
- */
-#define HMAC_SHA256_TEST_VECTORS       10
-
-static struct hash_testvec hmac_sha256_tv_template[] = {
-       {
-               .key    = "\x01\x02\x03\x04\x05\x06\x07\x08"
-                         "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
-                         "\x11\x12\x13\x14\x15\x16\x17\x18"
-                         "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20",
-               .ksize  = 32,
-               .plaintext = "abc",
-               .psize  = 3,
-               .digest = "\xa2\x1b\x1f\x5d\x4c\xf4\xf7\x3a"
-                         "\x4d\xd9\x39\x75\x0f\x7a\x06\x6a"
-                         "\x7f\x98\xcc\x13\x1c\xb1\x6a\x66"
-                         "\x92\x75\x90\x21\xcf\xab\x81\x81",
-       }, {
-               .key    = "\x01\x02\x03\x04\x05\x06\x07\x08"
-                         "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
-                         "\x11\x12\x13\x14\x15\x16\x17\x18"
-                         "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20",
-               .ksize  = 32,
-               .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
-               .psize  = 56,
-               .digest = "\x10\x4f\xdc\x12\x57\x32\x8f\x08"
-                         "\x18\x4b\xa7\x31\x31\xc5\x3c\xae"
-                         "\xe6\x98\xe3\x61\x19\x42\x11\x49"
-                         "\xea\x8c\x71\x24\x56\x69\x7d\x30",
-       }, {
-               .key    = "\x01\x02\x03\x04\x05\x06\x07\x08"
-                         "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
-                         "\x11\x12\x13\x14\x15\x16\x17\x18"
-                         "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20",
-               .ksize  = 32,
-               .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
-                          "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
-               .psize  = 112,
-               .digest = "\x47\x03\x05\xfc\x7e\x40\xfe\x34"
-                         "\xd3\xee\xb3\xe7\x73\xd9\x5a\xab"
-                         "\x73\xac\xf0\xfd\x06\x04\x47\xa5"
-                         "\xeb\x45\x95\xbf\x33\xa9\xd1\xa3",
-       }, {
-               .key    = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
-                       "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
-                       "\x0b\x0b\x0b\x0b\x0b\x0b",
-               .ksize  = 32,
-               .plaintext = "Hi There",
-               .psize  = 8,
-               .digest = "\x19\x8a\x60\x7e\xb4\x4b\xfb\xc6"
-                         "\x99\x03\xa0\xf1\xcf\x2b\xbd\xc5"
-                         "\xba\x0a\xa3\xf3\xd9\xae\x3c\x1c"
-                         "\x7a\x3b\x16\x96\xa0\xb6\x8c\xf7",
-       }, {
-               .key    = "Jefe",
-               .ksize  = 4,
-               .plaintext = "what do ya want for nothing?",
-               .psize  = 28,
-               .digest = "\x5b\xdc\xc1\x46\xbf\x60\x75\x4e"
-                         "\x6a\x04\x24\x26\x08\x95\x75\xc7"
-                         "\x5a\x00\x3f\x08\x9d\x27\x39\x83"
-                         "\x9d\xec\x58\xb9\x64\xec\x38\x43",
-               .np     = 2,
-               .tap    = { 14, 14 }
-       }, {
-               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
-               .ksize  = 32,
-               .plaintext = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
-                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
-                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
-                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
-               .psize  = 50,
-               .digest = "\xcd\xcb\x12\x20\xd1\xec\xcc\xea"
-                         "\x91\xe5\x3a\xba\x30\x92\xf9\x62"
-                         "\xe5\x49\xfe\x6c\xe9\xed\x7f\xdc"
-                         "\x43\x19\x1f\xbd\xe4\x5c\x30\xb0",
-       }, {
-               .key    = "\x01\x02\x03\x04\x05\x06\x07\x08"
-                         "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
-                         "\x11\x12\x13\x14\x15\x16\x17\x18"
-                         "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
-                         "\x21\x22\x23\x24\x25",
-               .ksize  = 37,
-               .plaintext = "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
-               .psize  = 50,
-               .digest = "\xd4\x63\x3c\x17\xf6\xfb\x8d\x74"
-                         "\x4c\x66\xde\xe0\xf8\xf0\x74\x55"
-                         "\x6e\xc4\xaf\x55\xef\x07\x99\x85"
-                         "\x41\x46\x8e\xb4\x9b\xd2\xe9\x17",
-       }, {
-               .key    = "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
-                       "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
-                       "\x0c\x0c\x0c\x0c\x0c\x0c",
-               .ksize  = 32,
-               .plaintext = "Test With Truncation",
-               .psize  = 20,
-               .digest = "\x75\x46\xaf\x01\x84\x1f\xc0\x9b"
-                         "\x1a\xb9\xc3\x74\x9a\x5f\x1c\x17"
-                         "\xd4\xf5\x89\x66\x8a\x58\x7b\x27"
-                         "\x00\xa9\xc9\x7c\x11\x93\xcf\x42",
-       }, {
-               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa",
-               .ksize  = 80,
-               .plaintext = "Test Using Larger Than Block-Size Key - Hash Key First",
-               .psize  = 54,
-               .digest = "\x69\x53\x02\x5e\xd9\x6f\x0c\x09"
-                         "\xf8\x0a\x96\xf7\x8e\x65\x38\xdb"
-                         "\xe2\xe7\xb8\x20\xe3\xdd\x97\x0e"
-                         "\x7d\xdd\x39\x09\x1b\x32\x35\x2f",
-       }, {
-               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa",
-               .ksize  = 80,
-               .plaintext = "Test Using Larger Than Block-Size Key and Larger Than "
-                          "One Block-Size Data",
-               .psize  = 73,
-               .digest = "\x63\x55\xac\x22\xe8\x90\xd0\xa3"
-                         "\xc8\x48\x1a\x5c\xa4\x82\x5b\xc8"
-                         "\x84\xd3\xe7\xa1\xff\x98\xa2\xfc"
-                         "\x2a\xc7\xd8\xe0\x64\xc3\xb2\xe6",
-       },
-};
-
-#define XCBC_AES_TEST_VECTORS 6
-
-static struct hash_testvec aes_xcbc128_tv_template[] = {
-       {
-               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-               .plaintext = zeroed_string,
-               .digest = "\x75\xf0\x25\x1d\x52\x8a\xc0\x1c"
-                         "\x45\x73\xdf\xd5\x84\xd7\x9f\x29",
-               .psize  = 0,
-               .ksize  = 16,
-       }, {
-               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-               .plaintext = "\x00\x01\x02",
-               .digest = "\x5b\x37\x65\x80\xae\x2f\x19\xaf"
-                         "\xe7\x21\x9c\xee\xf1\x72\x75\x6f",
-               .psize  = 3,
-               .ksize  = 16,
-       } , {
-               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-               .plaintext = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                            "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-               .digest = "\xd2\xa2\x46\xfa\x34\x9b\x68\xa7"
-                         "\x99\x98\xa4\x39\x4f\xf7\xa2\x63",
-               .psize  = 16,
-               .ksize  = 16,
-       }, {
-               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-               .plaintext = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                            "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                            "\x10\x11\x12\x13",
-               .digest = "\x47\xf5\x1b\x45\x64\x96\x62\x15"
-                         "\xb8\x98\x5c\x63\x05\x5e\xd3\x08",
-               .tap    = { 10, 10 },
-               .psize  = 20,
-               .np     = 2,
-               .ksize  = 16,
-       }, {
-               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-               .plaintext = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                            "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                            "\x10\x11\x12\x13\x14\x15\x16\x17"
-                            "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
-               .digest = "\xf5\x4f\x0e\xc8\xd2\xb9\xf3\xd3"
-                         "\x68\x07\x73\x4b\xd5\x28\x3f\xd4",
-               .psize  = 32,
-               .ksize  = 16,
-       }, {
-               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-               .plaintext = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                            "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                            "\x10\x11\x12\x13\x14\x15\x16\x17"
-                            "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
-                            "\x20\x21",
-               .digest = "\xbe\xcb\xb3\xbc\xcd\xb5\x18\xa3"
-                         "\x06\x77\xd5\x48\x1f\xb6\xb4\xd8",
-               .tap    = { 17, 17 },
-               .psize  = 34,
-               .np     = 2,
-               .ksize  = 16,
-       }
-};
-
-/*
- * SHA384 HMAC test vectors from RFC4231
- */
-
-#define HMAC_SHA384_TEST_VECTORS       4
-
-static struct hash_testvec hmac_sha384_tv_template[] = {
-       {
-               .key    = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
-                         "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
-                         "\x0b\x0b\x0b\x0b",
-               .ksize  = 20,
-               .plaintext = "Hi There",
-               .psize  = 8,
-               .digest = "\xaf\xd0\x39\x44\xd8\x48\x95\x62"
-                         "\x6b\x08\x25\xf4\xab\x46\x90\x7f"
-                         "\x15\xf9\xda\xdb\xe4\x10\x1e\xc6"
-                         "\x82\xaa\x03\x4c\x7c\xeb\xc5\x9c"
-                         "\xfa\xea\x9e\xa9\x07\x6e\xde\x7f"
-                         "\x4a\xf1\x52\xe8\xb2\xfa\x9c\xb6",
-       }, {
-               .key    = "Jefe",
-               .ksize  = 4,
-               .plaintext = "what do ya want for nothing?",
-               .psize  = 28,
-               .digest = "\xaf\x45\xd2\xe3\x76\x48\x40\x31"
-                         "\x61\x7f\x78\xd2\xb5\x8a\x6b\x1b"
-                         "\x9c\x7e\xf4\x64\xf5\xa0\x1b\x47"
-                         "\xe4\x2e\xc3\x73\x63\x22\x44\x5e"
-                         "\x8e\x22\x40\xca\x5e\x69\xe2\xc7"
-                         "\x8b\x32\x39\xec\xfa\xb2\x16\x49",
-               .np     = 4,
-               .tap    = { 7, 7, 7, 7 }
-       }, {
-               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa",
-               .ksize  = 131,
-               .plaintext = "Test Using Larger Than Block-Siz"
-                          "e Key - Hash Key First",
-               .psize  = 54,
-               .digest = "\x4e\xce\x08\x44\x85\x81\x3e\x90"
-                         "\x88\xd2\xc6\x3a\x04\x1b\xc5\xb4"
-                         "\x4f\x9e\xf1\x01\x2a\x2b\x58\x8f"
-                         "\x3c\xd1\x1f\x05\x03\x3a\xc4\xc6"
-                         "\x0c\x2e\xf6\xab\x40\x30\xfe\x82"
-                         "\x96\x24\x8d\xf1\x63\xf4\x49\x52",
-       }, {
-               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa",
-               .ksize  = 131,
-               .plaintext = "This is a test u"
-                          "sing a larger th"
-                          "an block-size ke"
-                          "y and a larger t"
-                          "han block-size d"
-                          "ata. The key nee"
-                          "ds to be hashed "
-                          "before being use"
-                          "d by the HMAC al"
-                          "gorithm.",
-               .psize  = 152,
-               .digest = "\x66\x17\x17\x8e\x94\x1f\x02\x0d"
-                         "\x35\x1e\x2f\x25\x4e\x8f\xd3\x2c"
-                         "\x60\x24\x20\xfe\xb0\xb8\xfb\x9a"
-                         "\xdc\xce\xbb\x82\x46\x1e\x99\xc5"
-                         "\xa6\x78\xcc\x31\xe7\x99\x17\x6d"
-                         "\x38\x60\xe6\x11\x0c\x46\x52\x3e",
-       },
-};
-
-/*
- * SHA512 HMAC test vectors from RFC4231
- */
-
-#define HMAC_SHA512_TEST_VECTORS       4
-
-static struct hash_testvec hmac_sha512_tv_template[] = {
-       {
-               .key    = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
-                         "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
-                         "\x0b\x0b\x0b\x0b",
-               .ksize  = 20,
-               .plaintext = "Hi There",
-               .psize  = 8,
-               .digest = "\x87\xaa\x7c\xde\xa5\xef\x61\x9d"
-                         "\x4f\xf0\xb4\x24\x1a\x1d\x6c\xb0"
-                         "\x23\x79\xf4\xe2\xce\x4e\xc2\x78"
-                         "\x7a\xd0\xb3\x05\x45\xe1\x7c\xde"
-                         "\xda\xa8\x33\xb7\xd6\xb8\xa7\x02"
-                         "\x03\x8b\x27\x4e\xae\xa3\xf4\xe4"
-                         "\xbe\x9d\x91\x4e\xeb\x61\xf1\x70"
-                         "\x2e\x69\x6c\x20\x3a\x12\x68\x54",
-       }, {
-               .key    = "Jefe",
-               .ksize  = 4,
-               .plaintext = "what do ya want for nothing?",
-               .psize  = 28,
-               .digest = "\x16\x4b\x7a\x7b\xfc\xf8\x19\xe2"
-                         "\xe3\x95\xfb\xe7\x3b\x56\xe0\xa3"
-                         "\x87\xbd\x64\x22\x2e\x83\x1f\xd6"
-                         "\x10\x27\x0c\xd7\xea\x25\x05\x54"
-                         "\x97\x58\xbf\x75\xc0\x5a\x99\x4a"
-                         "\x6d\x03\x4f\x65\xf8\xf0\xe6\xfd"
-                         "\xca\xea\xb1\xa3\x4d\x4a\x6b\x4b"
-                         "\x63\x6e\x07\x0a\x38\xbc\xe7\x37",
-               .np     = 4,
-               .tap    = { 7, 7, 7, 7 }
-       }, {
-               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                         "\xaa\xaa\xaa",
-               .ksize  = 131,
-               .plaintext = "Test Using Large"
-                          "r Than Block-Siz"
-                          "e Key - Hash Key"
-                          " First",
-               .psize  = 54,
-               .digest = "\x80\xb2\x42\x63\xc7\xc1\xa3\xeb"
-                       "\xb7\x14\x93\xc1\xdd\x7b\xe8\xb4"
-                       "\x9b\x46\xd1\xf4\x1b\x4a\xee\xc1"
-                       "\x12\x1b\x01\x37\x83\xf8\xf3\x52"
-                       "\x6b\x56\xd0\x37\xe0\x5f\x25\x98"
-                       "\xbd\x0f\xd2\x21\x5d\x6a\x1e\x52"
-                       "\x95\xe6\x4f\x73\xf6\x3f\x0a\xec"
-                       "\x8b\x91\x5a\x98\x5d\x78\x65\x98",
-       }, {
-               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-                       "\xaa\xaa\xaa",
-               .ksize  = 131,
-               .plaintext =
-                         "This is a test u"
-                         "sing a larger th"
-                         "an block-size ke"
-                         "y and a larger t"
-                         "han block-size d"
-                         "ata. The key nee"
-                         "ds to be hashed "
-                         "before being use"
-                         "d by the HMAC al"
-                         "gorithm.",
-               .psize  = 152,
-               .digest = "\xe3\x7b\x6a\x77\x5d\xc8\x7d\xba"
-                       "\xa4\xdf\xa9\xf9\x6e\x5e\x3f\xfd"
-                       "\xde\xbd\x71\xf8\x86\x72\x89\x86"
-                       "\x5d\xf5\xa3\x2d\x20\xcd\xc9\x44"
-                       "\xb6\x02\x2c\xac\x3c\x49\x82\xb1"
-                       "\x0d\x5e\xeb\x55\xc3\xe4\xde\x15"
-                       "\x13\x46\x76\xfb\x6d\xe0\x44\x60"
-                       "\x65\xc9\x74\x40\xfa\x8c\x6a\x58",
-       },
-};
-
 /*
  * DES test vectors.
  */
-#define DES_ENC_TEST_VECTORS           10
-#define DES_DEC_TEST_VECTORS           4
-#define DES_CBC_ENC_TEST_VECTORS       5
-#define DES_CBC_DEC_TEST_VECTORS       4
-#define DES3_EDE_ENC_TEST_VECTORS      3
-#define DES3_EDE_DEC_TEST_VECTORS      3
-#define DES3_EDE_CBC_ENC_TEST_VECTORS  1
-#define DES3_EDE_CBC_DEC_TEST_VECTORS  1
-
-static struct cipher_testvec des_enc_tv_template[] = {
-       { /* From Applied Cryptography */
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .klen   = 8,
-               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xe7",
-               .ilen   = 8,
-               .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d",
-               .rlen   = 8,
-       }, { /* Same key, different plaintext block */
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .klen   = 8,
-               .input  = "\x22\x33\x44\x55\x66\x77\x88\x99",
-               .ilen   = 8,
-               .result = "\xf7\x9c\x89\x2a\x33\x8f\x4a\x8b",
-               .rlen   = 8,
-       }, { /* Sbox test from NBS */
-               .key    = "\x7c\xa1\x10\x45\x4a\x1a\x6e\x57",
-               .klen   = 8,
-               .input  = "\x01\xa1\xd6\xd0\x39\x77\x67\x42",
-               .ilen   = 8,
-               .result = "\x69\x0f\x5b\x0d\x9a\x26\x93\x9b",
-               .rlen   = 8,
-       }, { /* Three blocks */
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .klen   = 8,
-               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xe7"
-                         "\x22\x33\x44\x55\x66\x77\x88\x99"
-                         "\xca\xfe\xba\xbe\xfe\xed\xbe\xef",
-               .ilen   = 24,
-               .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d"
-                         "\xf7\x9c\x89\x2a\x33\x8f\x4a\x8b"
-                         "\xb4\x99\x26\xf7\x1f\xe1\xd4\x90",
-               .rlen   = 24,
-       }, { /* Weak key */
-               .fail   = 1,
-               .wk     = 1,
-               .key    = "\x01\x01\x01\x01\x01\x01\x01\x01",
-               .klen   = 8,
-               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xe7",
-               .ilen   = 8,
-               .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d",
-               .rlen   = 8,
-       }, { /* Two blocks -- for testing encryption across pages */
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .klen   = 8,
-               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xe7"
-                         "\x22\x33\x44\x55\x66\x77\x88\x99",
-               .ilen   = 16,
-               .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d"
-                         "\xf7\x9c\x89\x2a\x33\x8f\x4a\x8b",
-               .rlen   = 16,
-               .np     = 2,
-               .tap    = { 8, 8 }
-       }, { /* Four blocks -- for testing encryption with chunking */
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .klen   = 8,
-               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xe7"
-                         "\x22\x33\x44\x55\x66\x77\x88\x99"
-                         "\xca\xfe\xba\xbe\xfe\xed\xbe\xef"
-                         "\x22\x33\x44\x55\x66\x77\x88\x99",
-               .ilen   = 32,
-               .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d"
-                         "\xf7\x9c\x89\x2a\x33\x8f\x4a\x8b"
-                         "\xb4\x99\x26\xf7\x1f\xe1\xd4\x90"
-                         "\xf7\x9c\x89\x2a\x33\x8f\x4a\x8b",
-               .rlen   = 32,
-               .np     = 3,
-               .tap    = { 14, 10, 8 }
-       }, {
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .klen   = 8,
-               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xe7"
-                         "\x22\x33\x44\x55\x66\x77\x88\x99"
-                         "\xca\xfe\xba\xbe\xfe\xed\xbe\xef",
-               .ilen   = 24,
-               .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d"
-                         "\xf7\x9c\x89\x2a\x33\x8f\x4a\x8b"
-                         "\xb4\x99\x26\xf7\x1f\xe1\xd4\x90",
-               .rlen   = 24,
-               .np     = 4,
-               .tap    = { 2, 1, 3, 18 }
-       }, {
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .klen   = 8,
-               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xe7"
-                         "\x22\x33\x44\x55\x66\x77\x88\x99",
-               .ilen   = 16,
-               .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d"
-                         "\xf7\x9c\x89\x2a\x33\x8f\x4a\x8b",
-               .rlen   = 16,
-               .np     = 5,
-               .tap    = { 2, 2, 2, 2, 8 }
-       }, {
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .klen   = 8,
-               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xe7",
-               .ilen   = 8,
-               .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d",
-               .rlen   = 8,
-               .np     = 8,
-               .tap    = { 1, 1, 1, 1, 1, 1, 1, 1 }
-       },
-};
-
-static struct cipher_testvec des_dec_tv_template[] = {
-       { /* From Applied Cryptography */
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .klen   = 8,
-               .input  = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d",
-               .ilen   = 8,
-               .result = "\x01\x23\x45\x67\x89\xab\xcd\xe7",
-               .rlen   = 8,
-       }, { /* Sbox test from NBS */
-               .key    = "\x7c\xa1\x10\x45\x4a\x1a\x6e\x57",
-               .klen   = 8,
-               .input  = "\x69\x0f\x5b\x0d\x9a\x26\x93\x9b",
-               .ilen   = 8,
-               .result = "\x01\xa1\xd6\xd0\x39\x77\x67\x42",
-               .rlen   = 8,
-       }, { /* Two blocks, for chunking test */
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .klen   = 8,
-               .input  = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d"
-                         "\x69\x0f\x5b\x0d\x9a\x26\x93\x9b",
-               .ilen   = 16,
-               .result = "\x01\x23\x45\x67\x89\xab\xcd\xe7"
-                         "\xa3\x99\x7b\xca\xaf\x69\xa0\xf5",
-               .rlen   = 16,
-               .np     = 2,
-               .tap    = { 8, 8 }
-       }, {
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .klen   = 8,
-               .input  = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d"
-                         "\x69\x0f\x5b\x0d\x9a\x26\x93\x9b",
-               .ilen   = 16,
-               .result = "\x01\x23\x45\x67\x89\xab\xcd\xe7"
-                         "\xa3\x99\x7b\xca\xaf\x69\xa0\xf5",
-               .rlen   = 16,
-               .np     = 3,
-               .tap    = { 3, 12, 1 }
-       },
-};
-
-static struct cipher_testvec des_cbc_enc_tv_template[] = {
-       { /* From OpenSSL */
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .klen   = 8,
-               .iv     = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
-               .input  = "\x37\x36\x35\x34\x33\x32\x31\x20"
-                         "\x4e\x6f\x77\x20\x69\x73\x20\x74"
-                         "\x68\x65\x20\x74\x69\x6d\x65\x20",
-               .ilen   = 24,
-               .result = "\xcc\xd1\x73\xff\xab\x20\x39\xf4"
-                         "\xac\xd8\xae\xfd\xdf\xd8\xa1\xeb"
-                         "\x46\x8e\x91\x15\x78\x88\xba\x68",
-               .rlen   = 24,
-       }, { /* FIPS Pub 81 */
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .klen   = 8,
-               .iv     = "\x12\x34\x56\x78\x90\xab\xcd\xef",
-               .input  = "\x4e\x6f\x77\x20\x69\x73\x20\x74",
-               .ilen   = 8,
-               .result = "\xe5\xc7\xcd\xde\x87\x2b\xf2\x7c",
-               .rlen   = 8,
-       }, {
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .klen   = 8,
-               .iv     = "\xe5\xc7\xcd\xde\x87\x2b\xf2\x7c",
-               .input  = "\x68\x65\x20\x74\x69\x6d\x65\x20",
-               .ilen   = 8,
-               .result = "\x43\xe9\x34\x00\x8c\x38\x9c\x0f",
-               .rlen   = 8,
-       }, {
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .klen   = 8,
-               .iv     = "\x43\xe9\x34\x00\x8c\x38\x9c\x0f",
-               .input  = "\x66\x6f\x72\x20\x61\x6c\x6c\x20",
-               .ilen   = 8,
-               .result = "\x68\x37\x88\x49\x9a\x7c\x05\xf6",
-               .rlen   = 8,
-       }, { /* Copy of openssl vector for chunk testing */
-            /* From OpenSSL */
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .klen   = 8,
-               .iv     = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
-               .input  = "\x37\x36\x35\x34\x33\x32\x31\x20"
-                         "\x4e\x6f\x77\x20\x69\x73\x20\x74"
-                         "\x68\x65\x20\x74\x69\x6d\x65\x20",
-               .ilen   = 24,
-               .result = "\xcc\xd1\x73\xff\xab\x20\x39\xf4"
-                         "\xac\xd8\xae\xfd\xdf\xd8\xa1\xeb"
-                         "\x46\x8e\x91\x15\x78\x88\xba\x68",
-               .rlen   = 24,
-               .np     = 2,
-               .tap    = { 13, 11 }
-       },
-};
-
-static struct cipher_testvec des_cbc_dec_tv_template[] = {
-       { /* FIPS Pub 81 */
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .klen   = 8,
-               .iv     = "\x12\x34\x56\x78\x90\xab\xcd\xef",
-               .input  = "\xe5\xc7\xcd\xde\x87\x2b\xf2\x7c",
-               .ilen   = 8,
-               .result = "\x4e\x6f\x77\x20\x69\x73\x20\x74",
-               .rlen   = 8,
-       }, {
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .klen   = 8,
-               .iv     = "\xe5\xc7\xcd\xde\x87\x2b\xf2\x7c",
-               .input  = "\x43\xe9\x34\x00\x8c\x38\x9c\x0f",
-               .ilen   = 8,
-               .result = "\x68\x65\x20\x74\x69\x6d\x65\x20",
-               .rlen   = 8,
-       }, {
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .klen   = 8,
-               .iv     = "\x43\xe9\x34\x00\x8c\x38\x9c\x0f",
-               .input  = "\x68\x37\x88\x49\x9a\x7c\x05\xf6",
-               .ilen   = 8,
-               .result = "\x66\x6f\x72\x20\x61\x6c\x6c\x20",
-               .rlen   = 8,
-       }, { /* Copy of above, for chunk testing */
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .klen   = 8,
-               .iv     = "\x43\xe9\x34\x00\x8c\x38\x9c\x0f",
-               .input  = "\x68\x37\x88\x49\x9a\x7c\x05\xf6",
-               .ilen   = 8,
-               .result = "\x66\x6f\x72\x20\x61\x6c\x6c\x20",
-               .rlen   = 8,
-               .np     = 2,
-               .tap    = { 4, 4 }
-       },
-};
-
-static struct cipher_testvec des3_ede_enc_tv_template[] = {
-       { /* These are from openssl */
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
-                         "\x55\x55\x55\x55\x55\x55\x55\x55"
-                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
-               .klen   = 24,
-               .input  = "\x73\x6f\x6d\x65\x64\x61\x74\x61",
-               .ilen   = 8,
-               .result = "\x18\xd7\x48\xe5\x63\x62\x05\x72",
-               .rlen   = 8,
-       }, {
-               .key    = "\x03\x52\x02\x07\x67\x20\x82\x17"
-                         "\x86\x02\x87\x66\x59\x08\x21\x98"
-                         "\x64\x05\x6a\xbd\xfe\xa9\x34\x57",
-               .klen   = 24,
-               .input  = "\x73\x71\x75\x69\x67\x67\x6c\x65",
-               .ilen   = 8,
-               .result = "\xc0\x7d\x2a\x0f\xa5\x66\xfa\x30",
-               .rlen   = 8,
-       }, {
-               .key    = "\x10\x46\x10\x34\x89\x98\x80\x20"
-                         "\x91\x07\xd0\x15\x89\x19\x01\x01"
-                         "\x19\x07\x92\x10\x98\x1a\x01\x01",
-               .klen   = 24,
-               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .ilen   = 8,
-               .result = "\xe1\xef\x62\xc3\x32\xfe\x82\x5b",
-               .rlen   = 8,
-       },
-};
-
-static struct cipher_testvec des3_ede_dec_tv_template[] = {
-       { /* These are from openssl */
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
-                         "\x55\x55\x55\x55\x55\x55\x55\x55"
-                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
-               .klen   = 24,
-               .input  = "\x18\xd7\x48\xe5\x63\x62\x05\x72",
-               .ilen   = 8,
-               .result = "\x73\x6f\x6d\x65\x64\x61\x74\x61",
-               .rlen   = 8,
-       }, {
-               .key    = "\x03\x52\x02\x07\x67\x20\x82\x17"
-                         "\x86\x02\x87\x66\x59\x08\x21\x98"
-                         "\x64\x05\x6a\xbd\xfe\xa9\x34\x57",
-               .klen   = 24,
-               .input  = "\xc0\x7d\x2a\x0f\xa5\x66\xfa\x30",
-               .ilen   = 8,
-               .result = "\x73\x71\x75\x69\x67\x67\x6c\x65",
-               .rlen   = 8,
-       }, {
-               .key    = "\x10\x46\x10\x34\x89\x98\x80\x20"
-                         "\x91\x07\xd0\x15\x89\x19\x01\x01"
-                         "\x19\x07\x92\x10\x98\x1a\x01\x01",
-               .klen   = 24,
-               .input  = "\xe1\xef\x62\xc3\x32\xfe\x82\x5b",
-               .ilen   = 8,
-               .result = "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .rlen   = 8,
-       },
-};
-
-static struct cipher_testvec des3_ede_cbc_enc_tv_template[] = {
-       { /* Generated from openssl */
-               .key    = "\xE9\xC0\xFF\x2E\x76\x0B\x64\x24"
-                         "\x44\x4D\x99\x5A\x12\xD6\x40\xC0"
-                         "\xEA\xC2\x84\xE8\x14\x95\xDB\xE8",
-               .klen   = 24,
-               .iv     = "\x7D\x33\x88\x93\x0F\x93\xB2\x42",
-               .input  = "\x6f\x54\x20\x6f\x61\x4d\x79\x6e"
-                         "\x53\x20\x63\x65\x65\x72\x73\x74"
-                         "\x54\x20\x6f\x6f\x4d\x20\x6e\x61"
-                         "\x20\x79\x65\x53\x72\x63\x74\x65"
-                         "\x20\x73\x6f\x54\x20\x6f\x61\x4d"
-                         "\x79\x6e\x53\x20\x63\x65\x65\x72"
-                         "\x73\x74\x54\x20\x6f\x6f\x4d\x20"
-                         "\x6e\x61\x20\x79\x65\x53\x72\x63"
-                         "\x74\x65\x20\x73\x6f\x54\x20\x6f"
-                         "\x61\x4d\x79\x6e\x53\x20\x63\x65"
-                         "\x65\x72\x73\x74\x54\x20\x6f\x6f"
-                         "\x4d\x20\x6e\x61\x20\x79\x65\x53"
-                         "\x72\x63\x74\x65\x20\x73\x6f\x54"
-                         "\x20\x6f\x61\x4d\x79\x6e\x53\x20"
-                         "\x63\x65\x65\x72\x73\x74\x54\x20"
-                         "\x6f\x6f\x4d\x20\x6e\x61\x0a\x79",
-               .ilen   = 128,
-               .result = "\x0e\x2d\xb6\x97\x3c\x56\x33\xf4"
-                         "\x67\x17\x21\xc7\x6e\x8a\xd5\x49"
-                         "\x74\xb3\x49\x05\xc5\x1c\xd0\xed"
-                         "\x12\x56\x5c\x53\x96\xb6\x00\x7d"
-                         "\x90\x48\xfc\xf5\x8d\x29\x39\xcc"
-                         "\x8a\xd5\x35\x18\x36\x23\x4e\xd7"
-                         "\x76\xd1\xda\x0c\x94\x67\xbb\x04"
-                         "\x8b\xf2\x03\x6c\xa8\xcf\xb6\xea"
-                         "\x22\x64\x47\xaa\x8f\x75\x13\xbf"
-                         "\x9f\xc2\xc3\xf0\xc9\x56\xc5\x7a"
-                         "\x71\x63\x2e\x89\x7b\x1e\x12\xca"
-                         "\xe2\x5f\xaf\xd8\xa4\xf8\xc9\x7a"
-                         "\xd6\xf9\x21\x31\x62\x44\x45\xa6"
-                         "\xd6\xbc\x5a\xd3\x2d\x54\x43\xcc"
-                         "\x9d\xde\xa5\x70\xe9\x42\x45\x8a"
-                         "\x6b\xfa\xb1\x91\x13\xb0\xd9\x19",
-               .rlen   = 128,
-       },
-};
-
-static struct cipher_testvec des3_ede_cbc_dec_tv_template[] = {
-       { /* Generated from openssl */
-               .key    = "\xE9\xC0\xFF\x2E\x76\x0B\x64\x24"
-                         "\x44\x4D\x99\x5A\x12\xD6\x40\xC0"
-                         "\xEA\xC2\x84\xE8\x14\x95\xDB\xE8",
-               .klen   = 24,
-               .iv     = "\x7D\x33\x88\x93\x0F\x93\xB2\x42",
-               .input  = "\x0e\x2d\xb6\x97\x3c\x56\x33\xf4"
-                         "\x67\x17\x21\xc7\x6e\x8a\xd5\x49"
-                         "\x74\xb3\x49\x05\xc5\x1c\xd0\xed"
-                         "\x12\x56\x5c\x53\x96\xb6\x00\x7d"
-                         "\x90\x48\xfc\xf5\x8d\x29\x39\xcc"
-                         "\x8a\xd5\x35\x18\x36\x23\x4e\xd7"
-                         "\x76\xd1\xda\x0c\x94\x67\xbb\x04"
-                         "\x8b\xf2\x03\x6c\xa8\xcf\xb6\xea"
-                         "\x22\x64\x47\xaa\x8f\x75\x13\xbf"
-                         "\x9f\xc2\xc3\xf0\xc9\x56\xc5\x7a"
-                         "\x71\x63\x2e\x89\x7b\x1e\x12\xca"
-                         "\xe2\x5f\xaf\xd8\xa4\xf8\xc9\x7a"
-                         "\xd6\xf9\x21\x31\x62\x44\x45\xa6"
-                         "\xd6\xbc\x5a\xd3\x2d\x54\x43\xcc"
-                         "\x9d\xde\xa5\x70\xe9\x42\x45\x8a"
-                         "\x6b\xfa\xb1\x91\x13\xb0\xd9\x19",
-               .ilen   = 128,
-               .result = "\x6f\x54\x20\x6f\x61\x4d\x79\x6e"
-                         "\x53\x20\x63\x65\x65\x72\x73\x74"
-                         "\x54\x20\x6f\x6f\x4d\x20\x6e\x61"
-                         "\x20\x79\x65\x53\x72\x63\x74\x65"
-                         "\x20\x73\x6f\x54\x20\x6f\x61\x4d"
-                         "\x79\x6e\x53\x20\x63\x65\x65\x72"
-                         "\x73\x74\x54\x20\x6f\x6f\x4d\x20"
-                         "\x6e\x61\x20\x79\x65\x53\x72\x63"
-                         "\x74\x65\x20\x73\x6f\x54\x20\x6f"
-                         "\x61\x4d\x79\x6e\x53\x20\x63\x65"
-                         "\x65\x72\x73\x74\x54\x20\x6f\x6f"
-                         "\x4d\x20\x6e\x61\x20\x79\x65\x53"
-                         "\x72\x63\x74\x65\x20\x73\x6f\x54"
-                         "\x20\x6f\x61\x4d\x79\x6e\x53\x20"
-                         "\x63\x65\x65\x72\x73\x74\x54\x20"
-                         "\x6f\x6f\x4d\x20\x6e\x61\x0a\x79",
-               .rlen   = 128,
-       },
-};
-
-/*
- * Blowfish test vectors.
- */
-#define BF_ENC_TEST_VECTORS    6
-#define BF_DEC_TEST_VECTORS    6
-#define BF_CBC_ENC_TEST_VECTORS        1
-#define BF_CBC_DEC_TEST_VECTORS        1
-
-static struct cipher_testvec bf_enc_tv_template[] = {
-       { /* DES test vectors from OpenSSL */
-               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .klen   = 8,
-               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .ilen   = 8,
-               .result = "\x4e\xf9\x97\x45\x61\x98\xdd\x78",
-               .rlen   = 8,
-       }, {
-               .key    = "\x1f\x1f\x1f\x1f\x0e\x0e\x0e\x0e",
-               .klen   = 8,
-               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .ilen   = 8,
-               .result = "\xa7\x90\x79\x51\x08\xea\x3c\xae",
-               .rlen   = 8,
-       }, {
-               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
-               .klen   = 8,
-               .input  = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
-               .ilen   = 8,
-               .result = "\xe8\x7a\x24\x4e\x2c\xc8\x5e\x82",
-               .rlen   = 8,
-       }, { /* Vary the keylength... */
-               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87"
-                         "\x78\x69\x5a\x4b\x3c\x2d\x1e\x0f",
-               .klen   = 16,
-               .input  = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
-               .ilen   = 8,
-               .result = "\x93\x14\x28\x87\xee\x3b\xe1\x5c",
-               .rlen   = 8,
-       }, {
-               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87"
-                         "\x78\x69\x5a\x4b\x3c\x2d\x1e\x0f"
-                         "\x00\x11\x22\x33\x44",
-               .klen   = 21,
-               .input  = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
-               .ilen   = 8,
-               .result = "\xe6\xf5\x1e\xd7\x9b\x9d\xb2\x1f",
-               .rlen   = 8,
-       }, { /* Generated with bf488 */
-               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87"
-                         "\x78\x69\x5a\x4b\x3c\x2d\x1e\x0f"
-                         "\x00\x11\x22\x33\x44\x55\x66\x77"
-                         "\x04\x68\x91\x04\xc2\xfd\x3b\x2f"
-                         "\x58\x40\x23\x64\x1a\xba\x61\x76"
-                         "\x1f\x1f\x1f\x1f\x0e\x0e\x0e\x0e"
-                         "\xff\xff\xff\xff\xff\xff\xff\xff",
-               .klen   = 56,
-               .input  = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
-               .ilen   = 8,
-               .result = "\xc0\x45\x04\x01\x2e\x4e\x1f\x53",
-               .rlen   = 8,
-       },
-};
-
-static struct cipher_testvec bf_dec_tv_template[] = {
-       { /* DES test vectors from OpenSSL */
-               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .klen   = 8,
-               .input  = "\x4e\xf9\x97\x45\x61\x98\xdd\x78",
-               .ilen   = 8,
-               .result = "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .rlen   = 8,
-       }, {
-               .key    = "\x1f\x1f\x1f\x1f\x0e\x0e\x0e\x0e",
-               .klen   = 8,
-               .input  = "\xa7\x90\x79\x51\x08\xea\x3c\xae",
-               .ilen   = 8,
-               .result = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .rlen   = 8,
-       }, {
-               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
-               .klen   = 8,
-               .input  = "\xe8\x7a\x24\x4e\x2c\xc8\x5e\x82",
-               .ilen   = 8,
-               .result = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
-               .rlen   = 8,
-       }, { /* Vary the keylength... */
-               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87"
-                         "\x78\x69\x5a\x4b\x3c\x2d\x1e\x0f",
-               .klen   = 16,
-               .input  = "\x93\x14\x28\x87\xee\x3b\xe1\x5c",
-               .ilen   = 8,
-               .result = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
-               .rlen   = 8,
-       }, {
-               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87"
-                         "\x78\x69\x5a\x4b\x3c\x2d\x1e\x0f"
-                         "\x00\x11\x22\x33\x44",
-               .klen   = 21,
-               .input  = "\xe6\xf5\x1e\xd7\x9b\x9d\xb2\x1f",
-               .ilen   = 8,
-               .result = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
-               .rlen   = 8,
-       }, { /* Generated with bf488, using OpenSSL, Libgcrypt and Nettle */
-               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87"
-                         "\x78\x69\x5a\x4b\x3c\x2d\x1e\x0f"
-                         "\x00\x11\x22\x33\x44\x55\x66\x77"
-                         "\x04\x68\x91\x04\xc2\xfd\x3b\x2f"
-                         "\x58\x40\x23\x64\x1a\xba\x61\x76"
-                         "\x1f\x1f\x1f\x1f\x0e\x0e\x0e\x0e"
-                         "\xff\xff\xff\xff\xff\xff\xff\xff",
-               .klen   = 56,
-               .input  = "\xc0\x45\x04\x01\x2e\x4e\x1f\x53",
-               .ilen   = 8,
-               .result = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
-               .rlen   = 8,
-       },
-};
-
-static struct cipher_testvec bf_cbc_enc_tv_template[] = {
-       { /* From OpenSSL */
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
-                         "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
-               .klen   = 16,
-               .iv     = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
-               .input  = "\x37\x36\x35\x34\x33\x32\x31\x20"
-                         "\x4e\x6f\x77\x20\x69\x73\x20\x74"
-                         "\x68\x65\x20\x74\x69\x6d\x65\x20"
-                         "\x66\x6f\x72\x20\x00\x00\x00\x00",
-               .ilen   = 32,
-               .result = "\x6b\x77\xb4\xd6\x30\x06\xde\xe6"
-                         "\x05\xb1\x56\xe2\x74\x03\x97\x93"
-                         "\x58\xde\xb9\xe7\x15\x46\x16\xd9"
-                         "\x59\xf1\x65\x2b\xd5\xff\x92\xcc",
-               .rlen   = 32,
-       },
-};
-
-static struct cipher_testvec bf_cbc_dec_tv_template[] = {
-       { /* From OpenSSL */
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
-                         "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
-               .klen   = 16,
-               .iv     = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
-               .input  = "\x6b\x77\xb4\xd6\x30\x06\xde\xe6"
-                         "\x05\xb1\x56\xe2\x74\x03\x97\x93"
-                         "\x58\xde\xb9\xe7\x15\x46\x16\xd9"
-                         "\x59\xf1\x65\x2b\xd5\xff\x92\xcc",
-               .ilen   = 32,
-               .result = "\x37\x36\x35\x34\x33\x32\x31\x20"
-                         "\x4e\x6f\x77\x20\x69\x73\x20\x74"
-                         "\x68\x65\x20\x74\x69\x6d\x65\x20"
-                         "\x66\x6f\x72\x20\x00\x00\x00\x00",
-               .rlen   = 32,
-       },
-};
-
-/*
- * Twofish test vectors.
- */
-#define TF_ENC_TEST_VECTORS            3
-#define TF_DEC_TEST_VECTORS            3
-#define TF_CBC_ENC_TEST_VECTORS                4
-#define TF_CBC_DEC_TEST_VECTORS                4
-
-static struct cipher_testvec tf_enc_tv_template[] = {
-       {
-               .key    = zeroed_string,
-               .klen   = 16,
-               .input  = zeroed_string,
-               .ilen   = 16,
-               .result = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
-                         "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a",
-               .rlen   = 16,
-       }, {
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
-                         "\xfe\xdc\xba\x98\x76\x54\x32\x10"
-                         "\x00\x11\x22\x33\x44\x55\x66\x77",
-               .klen   = 24,
-               .input  = zeroed_string,
-               .ilen   = 16,
-               .result = "\xcf\xd1\xd2\xe5\xa9\xbe\x9c\xdf"
-                         "\x50\x1f\x13\xb8\x92\xbd\x22\x48",
-               .rlen   = 16,
-       }, {
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
-                         "\xfe\xdc\xba\x98\x76\x54\x32\x10"
-                         "\x00\x11\x22\x33\x44\x55\x66\x77"
-                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
-               .klen   = 32,
-               .input  = zeroed_string,
-               .ilen   = 16,
-               .result = "\x37\x52\x7b\xe0\x05\x23\x34\xb8"
-                         "\x9f\x0c\xfc\xca\xe8\x7c\xfa\x20",
-               .rlen   = 16,
-       },
-};
+#define DES3_SPEED_VECTORS     1
 
-static struct cipher_testvec tf_dec_tv_template[] = {
+static struct cipher_speed_template des3_speed_template[] = {
        {
-               .key    = zeroed_string,
-               .klen   = 16,
-               .input  = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
-                         "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a",
-               .ilen   = 16,
-               .result = zeroed_string,
-               .rlen   = 16,
-       }, {
                .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
-                         "\xfe\xdc\xba\x98\x76\x54\x32\x10"
-                         "\x00\x11\x22\x33\x44\x55\x66\x77",
-               .klen   = 24,
-               .input  = "\xcf\xd1\xd2\xe5\xa9\xbe\x9c\xdf"
-                         "\x50\x1f\x13\xb8\x92\xbd\x22\x48",
-               .ilen   = 16,
-               .result = zeroed_string,
-               .rlen   = 16,
-       }, {
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
-                         "\xfe\xdc\xba\x98\x76\x54\x32\x10"
-                         "\x00\x11\x22\x33\x44\x55\x66\x77"
-                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
-               .klen   = 32,
-               .input  = "\x37\x52\x7b\xe0\x05\x23\x34\xb8"
-                         "\x9f\x0c\xfc\xca\xe8\x7c\xfa\x20",
-               .ilen   = 16,
-               .result = zeroed_string,
-               .rlen   = 16,
-       },
-};
-
-static struct cipher_testvec tf_cbc_enc_tv_template[] = {
-       { /* Generated with Nettle */
-               .key    = zeroed_string,
-               .klen   = 16,
-               .iv     = zeroed_string,
-               .input  = zeroed_string,
-               .ilen   = 16,
-               .result = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
-                         "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a",
-               .rlen   = 16,
-       }, {
-               .key    = zeroed_string,
-               .klen   = 16,
-               .iv     = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
-                         "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a",
-               .input  = zeroed_string,
-               .ilen   = 16,
-               .result = "\xd4\x91\xdb\x16\xe7\xb1\xc3\x9e"
-                         "\x86\xcb\x08\x6b\x78\x9f\x54\x19",
-               .rlen   = 16,
-       }, {
-               .key    = zeroed_string,
-               .klen   = 16,
-               .iv     = "\xd4\x91\xdb\x16\xe7\xb1\xc3\x9e"
-                         "\x86\xcb\x08\x6b\x78\x9f\x54\x19",
-               .input  = zeroed_string,
-               .ilen   = 16,
-               .result = "\x05\xef\x8c\x61\xa8\x11\x58\x26"
-                         "\x34\xba\x5c\xb7\x10\x6a\xa6\x41",
-               .rlen   = 16,
-       }, {
-               .key    = zeroed_string,
-               .klen   = 16,
-               .iv     = zeroed_string,
-               .input  = zeroed_string,
-               .ilen   = 48,
-               .result = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
-                         "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a"
-                         "\xd4\x91\xdb\x16\xe7\xb1\xc3\x9e"
-                         "\x86\xcb\x08\x6b\x78\x9f\x54\x19"
-                         "\x05\xef\x8c\x61\xa8\x11\x58\x26"
-                         "\x34\xba\x5c\xb7\x10\x6a\xa6\x41",
-               .rlen   = 48,
-       },
-};
-
-static struct cipher_testvec tf_cbc_dec_tv_template[] = {
-       { /* Reverse of the first four above */
-               .key    = zeroed_string,
-               .klen   = 16,
-               .iv     = zeroed_string,
-               .input  = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
-                         "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a",
-               .ilen   = 16,
-               .result = zeroed_string,
-               .rlen   = 16,
-       }, {
-               .key    = zeroed_string,
-               .klen   = 16,
-               .iv     = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
-                         "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a",
-               .input  = "\xd4\x91\xdb\x16\xe7\xb1\xc3\x9e"
-                         "\x86\xcb\x08\x6b\x78\x9f\x54\x19",
-               .ilen   = 16,
-               .result = zeroed_string,
-               .rlen   = 16,
-       }, {
-               .key    = zeroed_string,
-               .klen   = 16,
-               .iv     = "\xd4\x91\xdb\x16\xe7\xb1\xc3\x9e"
-                         "\x86\xcb\x08\x6b\x78\x9f\x54\x19",
-               .input  = "\x05\xef\x8c\x61\xa8\x11\x58\x26"
-                         "\x34\xba\x5c\xb7\x10\x6a\xa6\x41",
-               .ilen   = 16,
-               .result = zeroed_string,
-               .rlen   = 16,
-       }, {
-               .key    = zeroed_string,
-               .klen   = 16,
-               .iv     = zeroed_string,
-               .input  = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
-                         "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a"
-                         "\xd4\x91\xdb\x16\xe7\xb1\xc3\x9e"
-                         "\x86\xcb\x08\x6b\x78\x9f\x54\x19"
-                         "\x05\xef\x8c\x61\xa8\x11\x58\x26"
-                         "\x34\xba\x5c\xb7\x10\x6a\xa6\x41",
-               .ilen   = 48,
-               .result = zeroed_string,
-               .rlen   = 48,
-       },
-};
-
-/*
- * Serpent test vectors.  These are backwards because Serpent writes
- * octet sequences in right-to-left mode.
- */
-#define SERPENT_ENC_TEST_VECTORS       4
-#define SERPENT_DEC_TEST_VECTORS       4
-
-#define TNEPRES_ENC_TEST_VECTORS       4
-#define TNEPRES_DEC_TEST_VECTORS       4
-
-static struct cipher_testvec serpent_enc_tv_template[] = {
-       {
-               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-               .ilen   = 16,
-               .result = "\x12\x07\xfc\xce\x9b\xd0\xd6\x47"
-                         "\x6a\xe9\x8f\xbe\xd1\x43\xa0\xe2",
-               .rlen   = 16,
-       }, {
-               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-               .klen   = 16,
-               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-               .ilen   = 16,
-               .result = "\x4c\x7d\x8a\x32\x80\x72\xa2\x2c"
-                         "\x82\x3e\x4a\x1f\x3a\xcd\xa1\x6d",
-               .rlen   = 16,
-       }, {
-               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                         "\x10\x11\x12\x13\x14\x15\x16\x17"
-                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
-               .klen   = 32,
-               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-               .ilen   = 16,
-               .result = "\xde\x26\x9f\xf8\x33\xe4\x32\xb8"
-                         "\x5b\x2e\x88\xd2\x70\x1c\xe7\x5c",
-               .rlen   = 16,
-       }, {
-               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80",
-               .klen   = 16,
-               .input  = zeroed_string,
-               .ilen   = 16,
-               .result = "\xdd\xd2\x6b\x98\xa5\xff\xd8\x2c"
-                         "\x05\x34\x5a\x9d\xad\xbf\xaf\x49",
-               .rlen   = 16,
-       },
-};
-
-static struct cipher_testvec tnepres_enc_tv_template[] = {
-       { /* KeySize=128, PT=0, I=1 */
-               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .key    = "\x80\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .klen   = 16,
-               .ilen   = 16,
-               .result = "\x49\xaf\xbf\xad\x9d\x5a\x34\x05"
-                         "\x2c\xd8\xff\xa5\x98\x6b\xd2\xdd",
-               .rlen   = 16,
-       }, { /* KeySize=192, PT=0, I=1 */
-               .key    = "\x80\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .klen   = 24,
-               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .ilen   = 16,
-               .result = "\xe7\x8e\x54\x02\xc7\x19\x55\x68"
-                         "\xac\x36\x78\xf7\xa3\xf6\x0c\x66",
-               .rlen   = 16,
-       }, { /* KeySize=256, PT=0, I=1 */
-               .key    = "\x80\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .klen   = 32,
-               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .ilen   = 16,
-               .result = "\xab\xed\x96\xe7\x66\xbf\x28\xcb"
-                         "\xc0\xeb\xd2\x1a\x82\xef\x08\x19",
-               .rlen   = 16,
-       }, { /* KeySize=256, I=257 */
-               .key    = "\x1f\x1e\x1d\x1c\x1b\x1a\x19\x18"
-                         "\x17\x16\x15\x14\x13\x12\x11\x10"
-                         "\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08"
-                         "\x07\x06\x05\x04\x03\x02\x01\x00",
-               .klen   = 32,
-               .input  = "\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08"
-                         "\x07\x06\x05\x04\x03\x02\x01\x00",
-               .ilen   = 16,
-               .result = "\x5c\xe7\x1c\x70\xd2\x88\x2e\x5b"
-                         "\xb8\x32\xe4\x33\xf8\x9f\x26\xde",
-               .rlen   = 16,
-       },
-};
-
-
-static struct cipher_testvec serpent_dec_tv_template[] = {
-       {
-               .input  = "\x12\x07\xfc\xce\x9b\xd0\xd6\x47"
-                         "\x6a\xe9\x8f\xbe\xd1\x43\xa0\xe2",
-               .ilen   = 16,
-               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-               .rlen   = 16,
-       }, {
-               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-               .klen   = 16,
-               .input  = "\x4c\x7d\x8a\x32\x80\x72\xa2\x2c"
-                         "\x82\x3e\x4a\x1f\x3a\xcd\xa1\x6d",
-               .ilen   = 16,
-               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-               .rlen   = 16,
-       }, {
-               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                         "\x10\x11\x12\x13\x14\x15\x16\x17"
-                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
-               .klen   = 32,
-               .input  = "\xde\x26\x9f\xf8\x33\xe4\x32\xb8"
-                         "\x5b\x2e\x88\xd2\x70\x1c\xe7\x5c",
-               .ilen   = 16,
-               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-               .rlen   = 16,
-       }, {
-               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80",
-               .klen   = 16,
-               .input  = "\xdd\xd2\x6b\x98\xa5\xff\xd8\x2c"
-                         "\x05\x34\x5a\x9d\xad\xbf\xaf\x49",
-               .ilen   = 16,
-               .result = zeroed_string,
-               .rlen   = 16,
-       },
-};
-
-static struct cipher_testvec tnepres_dec_tv_template[] = {
-       {
-               .input  = "\x41\xcc\x6b\x31\x59\x31\x45\x97"
-                         "\x6d\x6f\xbb\x38\x4b\x37\x21\x28",
-               .ilen   = 16,
-               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-               .rlen   = 16,
-       }, {
-               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-               .klen   = 16,
-               .input  = "\xea\xf4\xd7\xfc\xd8\x01\x34\x47"
-                         "\x81\x45\x0b\xfa\x0c\xd6\xad\x6e",
-               .ilen   = 16,
-               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-               .rlen   = 16,
-       }, {
-               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                         "\x10\x11\x12\x13\x14\x15\x16\x17"
-                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
-               .klen   = 32,
-               .input  = "\x64\xa9\x1a\x37\xed\x9f\xe7\x49"
-                         "\xa8\x4e\x76\xd6\xf5\x0d\x78\xee",
-               .ilen   = 16,
-               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-               .rlen   = 16,
-       }, { /* KeySize=128, I=121 */
-               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80",
-               .klen   = 16,
-               .input  = "\x3d\xda\xbf\xc0\x06\xda\xab\x06"
-                         "\x46\x2a\xf4\xef\x81\x54\x4e\x26",
-               .ilen   = 16,
-               .result = zeroed_string,
-               .rlen   = 16,
-       },
-};
-
-
-/* Cast6 test vectors from RFC 2612 */
-#define CAST6_ENC_TEST_VECTORS 3
-#define CAST6_DEC_TEST_VECTORS  3
-
-static struct cipher_testvec cast6_enc_tv_template[] = {
-       {
-               .key    = "\x23\x42\xbb\x9e\xfa\x38\x54\x2c"
-                         "\x0a\xf7\x56\x47\xf2\x9f\x61\x5d",
-               .klen   = 16,
-               .input  = zeroed_string,
-               .ilen   = 16,
-               .result = "\xc8\x42\xa0\x89\x72\xb4\x3d\x20"
-                         "\x83\x6c\x91\xd1\xb7\x53\x0f\x6b",
-               .rlen   = 16,
-       }, {
-               .key    = "\x23\x42\xbb\x9e\xfa\x38\x54\x2c"
-                         "\xbe\xd0\xac\x83\x94\x0a\xc2\x98"
-                         "\xba\xc7\x7a\x77\x17\x94\x28\x63",
-               .klen   = 24,
-               .input  = zeroed_string,
-               .ilen   = 16,
-               .result = "\x1b\x38\x6c\x02\x10\xdc\xad\xcb"
-                         "\xdd\x0e\x41\xaa\x08\xa7\xa7\xe8",
-               .rlen   = 16,
-       }, {
-               .key    = "\x23\x42\xbb\x9e\xfa\x38\x54\x2c"
-                         "\xbe\xd0\xac\x83\x94\x0a\xc2\x98"
-                         "\x8d\x7c\x47\xce\x26\x49\x08\x46"
-                         "\x1c\xc1\xb5\x13\x7a\xe6\xb6\x04",
-               .klen   = 32,
-               .input  = zeroed_string,
-               .ilen   = 16,
-               .result = "\x4f\x6a\x20\x38\x28\x68\x97\xb9"
-                         "\xc9\x87\x01\x36\x55\x33\x17\xfa",
-               .rlen   = 16,
-       },
-};
-
-static struct cipher_testvec cast6_dec_tv_template[] = {
-       {
-               .key    = "\x23\x42\xbb\x9e\xfa\x38\x54\x2c"
-                         "\x0a\xf7\x56\x47\xf2\x9f\x61\x5d",
-               .klen   = 16,
-               .input  = "\xc8\x42\xa0\x89\x72\xb4\x3d\x20"
-                         "\x83\x6c\x91\xd1\xb7\x53\x0f\x6b",
-               .ilen   = 16,
-               .result = zeroed_string,
-               .rlen   = 16,
-       }, {
-               .key    = "\x23\x42\xbb\x9e\xfa\x38\x54\x2c"
-                         "\xbe\xd0\xac\x83\x94\x0a\xc2\x98"
-                         "\xba\xc7\x7a\x77\x17\x94\x28\x63",
-               .klen   = 24,
-               .input  = "\x1b\x38\x6c\x02\x10\xdc\xad\xcb"
-                         "\xdd\x0e\x41\xaa\x08\xa7\xa7\xe8",
-               .ilen   = 16,
-               .result = zeroed_string,
-               .rlen   = 16,
-       }, {
-               .key    = "\x23\x42\xbb\x9e\xfa\x38\x54\x2c"
-                         "\xbe\xd0\xac\x83\x94\x0a\xc2\x98"
-                         "\x8d\x7c\x47\xce\x26\x49\x08\x46"
-                         "\x1c\xc1\xb5\x13\x7a\xe6\xb6\x04",
-               .klen   = 32,
-               .input  = "\x4f\x6a\x20\x38\x28\x68\x97\xb9"
-                         "\xc9\x87\x01\x36\x55\x33\x17\xfa",
-               .ilen   = 16,
-               .result = zeroed_string,
-               .rlen   = 16,
-       },
-};
-
-
-/*
- * AES test vectors.
- */
-#define AES_ENC_TEST_VECTORS 3
-#define AES_DEC_TEST_VECTORS 3
-#define AES_CBC_ENC_TEST_VECTORS 4
-#define AES_CBC_DEC_TEST_VECTORS 4
-#define AES_LRW_ENC_TEST_VECTORS 8
-#define AES_LRW_DEC_TEST_VECTORS 8
-#define AES_XTS_ENC_TEST_VECTORS 4
-#define AES_XTS_DEC_TEST_VECTORS 4
-#define AES_CTR_ENC_TEST_VECTORS 7
-#define AES_CTR_DEC_TEST_VECTORS 6
-#define AES_GCM_ENC_TEST_VECTORS 9
-#define AES_GCM_DEC_TEST_VECTORS 8
-#define AES_CCM_ENC_TEST_VECTORS 7
-#define AES_CCM_DEC_TEST_VECTORS 7
-
-static struct cipher_testvec aes_enc_tv_template[] = {
-       { /* From FIPS-197 */
-               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-               .klen   = 16,
-               .input  = "\x00\x11\x22\x33\x44\x55\x66\x77"
-                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
-               .ilen   = 16,
-               .result = "\x69\xc4\xe0\xd8\x6a\x7b\x04\x30"
-                         "\xd8\xcd\xb7\x80\x70\xb4\xc5\x5a",
-               .rlen   = 16,
-       }, {
-               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                         "\x10\x11\x12\x13\x14\x15\x16\x17",
-               .klen   = 24,
-               .input  = "\x00\x11\x22\x33\x44\x55\x66\x77"
-                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
-               .ilen   = 16,
-               .result = "\xdd\xa9\x7c\xa4\x86\x4c\xdf\xe0"
-                         "\x6e\xaf\x70\xa0\xec\x0d\x71\x91",
-               .rlen   = 16,
-       }, {
-               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                         "\x10\x11\x12\x13\x14\x15\x16\x17"
-                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
-               .klen   = 32,
-               .input  = "\x00\x11\x22\x33\x44\x55\x66\x77"
-                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
-               .ilen   = 16,
-               .result = "\x8e\xa2\xb7\xca\x51\x67\x45\xbf"
-                         "\xea\xfc\x49\x90\x4b\x49\x60\x89",
-               .rlen   = 16,
-       },
-};
-
-static struct cipher_testvec aes_dec_tv_template[] = {
-       { /* From FIPS-197 */
-               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-               .klen   = 16,
-               .input  = "\x69\xc4\xe0\xd8\x6a\x7b\x04\x30"
-                         "\xd8\xcd\xb7\x80\x70\xb4\xc5\x5a",
-               .ilen   = 16,
-               .result = "\x00\x11\x22\x33\x44\x55\x66\x77"
-                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
-               .rlen   = 16,
-       }, {
-               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                         "\x10\x11\x12\x13\x14\x15\x16\x17",
-               .klen   = 24,
-               .input  = "\xdd\xa9\x7c\xa4\x86\x4c\xdf\xe0"
-                         "\x6e\xaf\x70\xa0\xec\x0d\x71\x91",
-               .ilen   = 16,
-               .result = "\x00\x11\x22\x33\x44\x55\x66\x77"
-                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
-               .rlen   = 16,
-       }, {
-               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                         "\x10\x11\x12\x13\x14\x15\x16\x17"
-                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
-               .klen   = 32,
-               .input  = "\x8e\xa2\xb7\xca\x51\x67\x45\xbf"
-                         "\xea\xfc\x49\x90\x4b\x49\x60\x89",
-               .ilen   = 16,
-               .result = "\x00\x11\x22\x33\x44\x55\x66\x77"
-                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
-               .rlen   = 16,
-       },
-};
-
-static struct cipher_testvec aes_cbc_enc_tv_template[] = {
-       { /* From RFC 3602 */
-               .key    = "\x06\xa9\x21\x40\x36\xb8\xa1\x5b"
-                         "\x51\x2e\x03\xd5\x34\x12\x00\x06",
-               .klen   = 16,
-               .iv     = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30"
-                         "\xb4\x22\xda\x80\x2c\x9f\xac\x41",
-               .input  = "Single block msg",
-               .ilen   = 16,
-               .result = "\xe3\x53\x77\x9c\x10\x79\xae\xb8"
-                         "\x27\x08\x94\x2d\xbe\x77\x18\x1a",
-               .rlen   = 16,
-       }, {
-               .key    = "\xc2\x86\x69\x6d\x88\x7c\x9a\xa0"
-                         "\x61\x1b\xbb\x3e\x20\x25\xa4\x5a",
-               .klen   = 16,
-               .iv     = "\x56\x2e\x17\x99\x6d\x09\x3d\x28"
-                         "\xdd\xb3\xba\x69\x5a\x2e\x6f\x58",
-               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                         "\x10\x11\x12\x13\x14\x15\x16\x17"
-                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
-               .ilen   = 32,
-               .result = "\xd2\x96\xcd\x94\xc2\xcc\xcf\x8a"
-                         "\x3a\x86\x30\x28\xb5\xe1\xdc\x0a"
-                         "\x75\x86\x60\x2d\x25\x3c\xff\xf9"
-                         "\x1b\x82\x66\xbe\xa6\xd6\x1a\xb1",
-               .rlen   = 32,
-       }, { /* From NIST SP800-38A */
-               .key    = "\x8e\x73\xb0\xf7\xda\x0e\x64\x52"
-                         "\xc8\x10\xf3\x2b\x80\x90\x79\xe5"
-                         "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
-               .klen   = 24,
-               .iv     = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-               .input  = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
-                         "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
-                         "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
-                         "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
-                         "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
-                         "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
-                         "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
-                         "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
-               .ilen   = 64,
-               .result = "\x4f\x02\x1d\xb2\x43\xbc\x63\x3d"
-                         "\x71\x78\x18\x3a\x9f\xa0\x71\xe8"
-                         "\xb4\xd9\xad\xa9\xad\x7d\xed\xf4"
-                         "\xe5\xe7\x38\x76\x3f\x69\x14\x5a"
-                         "\x57\x1b\x24\x20\x12\xfb\x7a\xe0"
-                         "\x7f\xa9\xba\xac\x3d\xf1\x02\xe0"
-                         "\x08\xb0\xe2\x79\x88\x59\x88\x81"
-                         "\xd9\x20\xa9\xe6\x4f\x56\x15\xcd",
-               .rlen   = 64,
-       }, {
-               .key    = "\x60\x3d\xeb\x10\x15\xca\x71\xbe"
-                         "\x2b\x73\xae\xf0\x85\x7d\x77\x81"
-                         "\x1f\x35\x2c\x07\x3b\x61\x08\xd7"
-                         "\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
-               .klen   = 32,
-               .iv     = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-               .input  = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
-                         "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
-                         "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
-                         "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
-                         "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
-                         "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
-                         "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
-                         "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
-               .ilen   = 64,
-               .result = "\xf5\x8c\x4c\x04\xd6\xe5\xf1\xba"
-                         "\x77\x9e\xab\xfb\x5f\x7b\xfb\xd6"
-                         "\x9c\xfc\x4e\x96\x7e\xdb\x80\x8d"
-                         "\x67\x9f\x77\x7b\xc6\x70\x2c\x7d"
-                         "\x39\xf2\x33\x69\xa9\xd9\xba\xcf"
-                         "\xa5\x30\xe2\x63\x04\x23\x14\x61"
-                         "\xb2\xeb\x05\xe2\xc3\x9b\xe9\xfc"
-                         "\xda\x6c\x19\x07\x8c\x6a\x9d\x1b",
-               .rlen   = 64,
-       },
-};
-
-static struct cipher_testvec aes_cbc_dec_tv_template[] = {
-       { /* From RFC 3602 */
-               .key    = "\x06\xa9\x21\x40\x36\xb8\xa1\x5b"
-                         "\x51\x2e\x03\xd5\x34\x12\x00\x06",
-               .klen   = 16,
-               .iv     = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30"
-                         "\xb4\x22\xda\x80\x2c\x9f\xac\x41",
-               .input  = "\xe3\x53\x77\x9c\x10\x79\xae\xb8"
-                         "\x27\x08\x94\x2d\xbe\x77\x18\x1a",
-               .ilen   = 16,
-               .result = "Single block msg",
-               .rlen   = 16,
-       }, {
-               .key    = "\xc2\x86\x69\x6d\x88\x7c\x9a\xa0"
-                         "\x61\x1b\xbb\x3e\x20\x25\xa4\x5a",
-               .klen   = 16,
-               .iv     = "\x56\x2e\x17\x99\x6d\x09\x3d\x28"
-                         "\xdd\xb3\xba\x69\x5a\x2e\x6f\x58",
-               .input  = "\xd2\x96\xcd\x94\xc2\xcc\xcf\x8a"
-                         "\x3a\x86\x30\x28\xb5\xe1\xdc\x0a"
-                         "\x75\x86\x60\x2d\x25\x3c\xff\xf9"
-                         "\x1b\x82\x66\xbe\xa6\xd6\x1a\xb1",
-               .ilen   = 32,
-               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                         "\x10\x11\x12\x13\x14\x15\x16\x17"
-                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
-               .rlen   = 32,
-       }, { /* From NIST SP800-38A */
-               .key    = "\x8e\x73\xb0\xf7\xda\x0e\x64\x52"
-                         "\xc8\x10\xf3\x2b\x80\x90\x79\xe5"
-                         "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
-               .klen   = 24,
-               .iv     = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-               .input  = "\x4f\x02\x1d\xb2\x43\xbc\x63\x3d"
-                         "\x71\x78\x18\x3a\x9f\xa0\x71\xe8"
-                         "\xb4\xd9\xad\xa9\xad\x7d\xed\xf4"
-                         "\xe5\xe7\x38\x76\x3f\x69\x14\x5a"
-                         "\x57\x1b\x24\x20\x12\xfb\x7a\xe0"
-                         "\x7f\xa9\xba\xac\x3d\xf1\x02\xe0"
-                         "\x08\xb0\xe2\x79\x88\x59\x88\x81"
-                         "\xd9\x20\xa9\xe6\x4f\x56\x15\xcd",
-               .ilen   = 64,
-               .result = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
-                         "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
-                         "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
-                         "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
-                         "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
-                         "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
-                         "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
-                         "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
-               .rlen   = 64,
-       }, {
-               .key    = "\x60\x3d\xeb\x10\x15\xca\x71\xbe"
-                         "\x2b\x73\xae\xf0\x85\x7d\x77\x81"
-                         "\x1f\x35\x2c\x07\x3b\x61\x08\xd7"
-                         "\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
-               .klen   = 32,
-               .iv     = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-               .input  = "\xf5\x8c\x4c\x04\xd6\xe5\xf1\xba"
-                         "\x77\x9e\xab\xfb\x5f\x7b\xfb\xd6"
-                         "\x9c\xfc\x4e\x96\x7e\xdb\x80\x8d"
-                         "\x67\x9f\x77\x7b\xc6\x70\x2c\x7d"
-                         "\x39\xf2\x33\x69\xa9\xd9\xba\xcf"
-                         "\xa5\x30\xe2\x63\x04\x23\x14\x61"
-                         "\xb2\xeb\x05\xe2\xc3\x9b\xe9\xfc"
-                         "\xda\x6c\x19\x07\x8c\x6a\x9d\x1b",
-               .ilen   = 64,
-               .result = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
-                         "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
-                         "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
-                         "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
-                         "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
-                         "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
-                         "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
-                         "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
-               .rlen   = 64,
-       },
-};
-
-static struct cipher_testvec aes_lrw_enc_tv_template[] = {
-       /* from http://grouper.ieee.org/groups/1619/email/pdf00017.pdf */
-       { /* LRW-32-AES 1 */
-               .key    = "\x45\x62\xac\x25\xf8\x28\x17\x6d"
-                         "\x4c\x26\x84\x14\xb5\x68\x01\x85"
-                         "\x25\x8e\x2a\x05\xe7\x3e\x9d\x03"
-                         "\xee\x5a\x83\x0c\xcc\x09\x4c\x87",
-               .klen   = 32,
-               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x01",
-               .input  = "\x30\x31\x32\x33\x34\x35\x36\x37"
-                         "\x38\x39\x41\x42\x43\x44\x45\x46",
-               .ilen   = 16,
-               .result = "\xf1\xb2\x73\xcd\x65\xa3\xdf\x5f"
-                         "\xe9\x5d\x48\x92\x54\x63\x4e\xb8",
-               .rlen   = 16,
-       }, { /* LRW-32-AES 2 */
-               .key    = "\x59\x70\x47\x14\xf5\x57\x47\x8c"
-                         "\xd7\x79\xe8\x0f\x54\x88\x79\x44"
-                         "\x0d\x48\xf0\xb7\xb1\x5a\x53\xea"
-                         "\x1c\xaa\x6b\x29\xc2\xca\xfb\xaf",
-               .klen   = 32,
-               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x02",
-               .input  = "\x30\x31\x32\x33\x34\x35\x36\x37"
-                         "\x38\x39\x41\x42\x43\x44\x45\x46",
-               .ilen   = 16,
-               .result = "\x00\xc8\x2b\xae\x95\xbb\xcd\xe5"
-                         "\x27\x4f\x07\x69\xb2\x60\xe1\x36",
-               .rlen   = 16,
-       }, { /* LRW-32-AES 3 */
-               .key    = "\xd8\x2a\x91\x34\xb2\x6a\x56\x50"
-                         "\x30\xfe\x69\xe2\x37\x7f\x98\x47"
-                         "\xcd\xf9\x0b\x16\x0c\x64\x8f\xb6"
-                         "\xb0\x0d\x0d\x1b\xae\x85\x87\x1f",
-               .klen   = 32,
-               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x02\x00\x00\x00\x00",
-               .input  = "\x30\x31\x32\x33\x34\x35\x36\x37"
-                         "\x38\x39\x41\x42\x43\x44\x45\x46",
-               .ilen   = 16,
-               .result = "\x76\x32\x21\x83\xed\x8f\xf1\x82"
-                         "\xf9\x59\x62\x03\x69\x0e\x5e\x01",
-               .rlen   = 16,
-       }, { /* LRW-32-AES 4 */
-               .key    = "\x0f\x6a\xef\xf8\xd3\xd2\xbb\x15"
-                         "\x25\x83\xf7\x3c\x1f\x01\x28\x74"
-                         "\xca\xc6\xbc\x35\x4d\x4a\x65\x54"
-                         "\x90\xae\x61\xcf\x7b\xae\xbd\xcc"
-                         "\xad\xe4\x94\xc5\x4a\x29\xae\x70",
-               .klen   = 40,
-               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x01",
-               .input  = "\x30\x31\x32\x33\x34\x35\x36\x37"
-                         "\x38\x39\x41\x42\x43\x44\x45\x46",
-               .ilen   = 16,
-               .result = "\x9c\x0f\x15\x2f\x55\xa2\xd8\xf0"
-                         "\xd6\x7b\x8f\x9e\x28\x22\xbc\x41",
-               .rlen   = 16,
-       }, { /* LRW-32-AES 5 */
-               .key    = "\x8a\xd4\xee\x10\x2f\xbd\x81\xff"
-                         "\xf8\x86\xce\xac\x93\xc5\xad\xc6"
-                         "\xa0\x19\x07\xc0\x9d\xf7\xbb\xdd"
-                         "\x52\x13\xb2\xb7\xf0\xff\x11\xd8"
-                         "\xd6\x08\xd0\xcd\x2e\xb1\x17\x6f",
-               .klen   = 40,
-               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x02\x00\x00\x00\x00",
-               .input  = "\x30\x31\x32\x33\x34\x35\x36\x37"
-                         "\x38\x39\x41\x42\x43\x44\x45\x46",
-               .ilen   = 16,
-               .result = "\xd4\x27\x6a\x7f\x14\x91\x3d\x65"
-                         "\xc8\x60\x48\x02\x87\xe3\x34\x06",
-               .rlen   = 16,
-       }, { /* LRW-32-AES 6 */
-               .key    = "\xf8\xd4\x76\xff\xd6\x46\xee\x6c"
-                         "\x23\x84\xcb\x1c\x77\xd6\x19\x5d"
-                         "\xfe\xf1\xa9\xf3\x7b\xbc\x8d\x21"
-                         "\xa7\x9c\x21\xf8\xcb\x90\x02\x89"
-                         "\xa8\x45\x34\x8e\xc8\xc5\xb5\xf1"
-                         "\x26\xf5\x0e\x76\xfe\xfd\x1b\x1e",
-               .klen   = 48,
-               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x01",
-               .input  = "\x30\x31\x32\x33\x34\x35\x36\x37"
-                         "\x38\x39\x41\x42\x43\x44\x45\x46",
-               .ilen   = 16,
-               .result = "\xbd\x06\xb8\xe1\xdb\x98\x89\x9e"
-                         "\xc4\x98\xe4\x91\xcf\x1c\x70\x2b",
-               .rlen   = 16,
-       }, { /* LRW-32-AES 7 */
-               .key    = "\xfb\x76\x15\xb2\x3d\x80\x89\x1d"
-                         "\xd4\x70\x98\x0b\xc7\x95\x84\xc8"
-                         "\xb2\xfb\x64\xce\x60\x97\x87\x8d"
-                         "\x17\xfc\xe4\x5a\x49\xe8\x30\xb7"
-                         "\x6e\x78\x17\xe7\x2d\x5e\x12\xd4"
-                         "\x60\x64\x04\x7a\xf1\x2f\x9e\x0c",
-               .klen   = 48,
-               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x02\x00\x00\x00\x00",
-               .input  = "\x30\x31\x32\x33\x34\x35\x36\x37"
-                         "\x38\x39\x41\x42\x43\x44\x45\x46",
-               .ilen   = 16,
-               .result = "\x5b\x90\x8e\xc1\xab\xdd\x67\x5f"
-                         "\x3d\x69\x8a\x95\x53\xc8\x9c\xe5",
-               .rlen   = 16,
-       }, {
-/* http://www.mail-archive.com/stds-p1619@listserv.ieee.org/msg00173.html */
-               .key    = "\xf8\xd4\x76\xff\xd6\x46\xee\x6c"
-                         "\x23\x84\xcb\x1c\x77\xd6\x19\x5d"
-                         "\xfe\xf1\xa9\xf3\x7b\xbc\x8d\x21"
-                         "\xa7\x9c\x21\xf8\xcb\x90\x02\x89"
-                         "\xa8\x45\x34\x8e\xc8\xc5\xb5\xf1"
-                         "\x26\xf5\x0e\x76\xfe\xfd\x1b\x1e",
-               .klen   = 48,
-               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x01",
-               .input  = "\x05\x11\xb7\x18\xab\xc6\x2d\xac"
-                         "\x70\x5d\xf6\x22\x94\xcd\xe5\x6c"
-                         "\x17\x6b\xf6\x1c\xf0\xf3\x6e\xf8"
-                         "\x50\x38\x1f\x71\x49\xb6\x57\xd6"
-                         "\x8f\xcb\x8d\x6b\xe3\xa6\x29\x90"
-                         "\xfe\x2a\x62\x82\xae\x6d\x8b\xf6"
-                         "\xad\x1e\x9e\x20\x5f\x38\xbe\x04"
-                         "\xda\x10\x8e\xed\xa2\xa4\x87\xab"
-                         "\xda\x6b\xb4\x0c\x75\xba\xd3\x7c"
-                         "\xc9\xac\x42\x31\x95\x7c\xc9\x04"
-                         "\xeb\xd5\x6e\x32\x69\x8a\xdb\xa6"
-                         "\x15\xd7\x3f\x4f\x2f\x66\x69\x03"
-                         "\x9c\x1f\x54\x0f\xde\x1f\xf3\x65"
-                         "\x4c\x96\x12\xed\x7c\x92\x03\x01"
-                         "\x6f\xbc\x35\x93\xac\xf1\x27\xf1"
-                         "\xb4\x96\x82\x5a\x5f\xb0\xa0\x50"
-                         "\x89\xa4\x8e\x66\x44\x85\xcc\xfd"
-                         "\x33\x14\x70\xe3\x96\xb2\xc3\xd3"
-                         "\xbb\x54\x5a\x1a\xf9\x74\xa2\xc5"
-                         "\x2d\x64\x75\xdd\xb4\x54\xe6\x74"
-                         "\x8c\xd3\x9d\x9e\x86\xab\x51\x53"
-                         "\xb7\x93\x3e\x6f\xd0\x4e\x2c\x40"
-                         "\xf6\xa8\x2e\x3e\x9d\xf4\x66\xa5"
-                         "\x76\x12\x73\x44\x1a\x56\xd7\x72"
-                         "\x88\xcd\x21\x8c\x4c\x0f\xfe\xda"
-                         "\x95\xe0\x3a\xa6\xa5\x84\x46\xcd"
-                         "\xd5\x3e\x9d\x3a\xe2\x67\xe6\x60"
-                         "\x1a\xe2\x70\x85\x58\xc2\x1b\x09"
-                         "\xe1\xd7\x2c\xca\xad\xa8\x8f\xf9"
-                         "\xac\xb3\x0e\xdb\xca\x2e\xe2\xb8"
-                         "\x51\x71\xd9\x3c\x6c\xf1\x56\xf8"
-                         "\xea\x9c\xf1\xfb\x0c\xe6\xb7\x10"
-                         "\x1c\xf8\xa9\x7c\xe8\x53\x35\xc1"
-                         "\x90\x3e\x76\x4a\x74\xa4\x21\x2c"
-                         "\xf6\x2c\x4e\x0f\x94\x3a\x88\x2e"
-                         "\x41\x09\x6a\x33\x7d\xf6\xdd\x3f"
-                         "\x8d\x23\x31\x74\x84\xeb\x88\x6e"
-                         "\xcc\xb9\xbc\x22\x83\x19\x07\x22"
-                         "\xa5\x2d\xdf\xa5\xf3\x80\x85\x78"
-                         "\x84\x39\x6a\x6d\x6a\x99\x4f\xa5"
-                         "\x15\xfe\x46\xb0\xe4\x6c\xa5\x41"
-                         "\x3c\xce\x8f\x42\x60\x71\xa7\x75"
-                         "\x08\x40\x65\x8a\x82\xbf\xf5\x43"
-                         "\x71\x96\xa9\x4d\x44\x8a\x20\xbe"
-                         "\xfa\x4d\xbb\xc0\x7d\x31\x96\x65"
-                         "\xe7\x75\xe5\x3e\xfd\x92\x3b\xc9"
-                         "\x55\xbb\x16\x7e\xf7\xc2\x8c\xa4"
-                         "\x40\x1d\xe5\xef\x0e\xdf\xe4\x9a"
-                         "\x62\x73\x65\xfd\x46\x63\x25\x3d"
-                         "\x2b\xaf\xe5\x64\xfe\xa5\x5c\xcf"
-                         "\x24\xf3\xb4\xac\x64\xba\xdf\x4b"
-                         "\xc6\x96\x7d\x81\x2d\x8d\x97\xf7"
-                         "\xc5\x68\x77\x84\x32\x2b\xcc\x85"
-                         "\x74\x96\xf0\x12\x77\x61\xb9\xeb"
-                         "\x71\xaa\x82\xcb\x1c\xdb\x89\xc8"
-                         "\xc6\xb5\xe3\x5c\x7d\x39\x07\x24"
-                         "\xda\x39\x87\x45\xc0\x2b\xbb\x01"
-                         "\xac\xbc\x2a\x5c\x7f\xfc\xe8\xce"
-                         "\x6d\x9c\x6f\xed\xd3\xc1\xa1\xd6"
-                         "\xc5\x55\xa9\x66\x2f\xe1\xc8\x32"
-                         "\xa6\x5d\xa4\x3a\x98\x73\xe8\x45"
-                         "\xa4\xc7\xa8\xb4\xf6\x13\x03\xf6"
-                         "\xe9\x2e\xc4\x29\x0f\x84\xdb\xc4"
-                         "\x21\xc4\xc2\x75\x67\x89\x37\x0a",
-               .ilen   = 512,
-               .result = "\x1a\x1d\xa9\x30\xad\xf9\x2f\x9b"
-                         "\xb6\x1d\xae\xef\xf0\x2f\xf8\x5a"
-                         "\x39\x3c\xbf\x2a\xb2\x45\xb2\x23"
-                         "\x1b\x63\x3c\xcf\xaa\xbe\xcf\x4e"
-                         "\xfa\xe8\x29\xc2\x20\x68\x2b\x3c"
-                         "\x2e\x8b\xf7\x6e\x25\xbd\xe3\x3d"
-                         "\x66\x27\xd6\xaf\xd6\x64\x3e\xe3"
-                         "\xe8\x58\x46\x97\x39\x51\x07\xde"
-                         "\xcb\x37\xbc\xa9\xc0\x5f\x75\xc3"
-                         "\x0e\x84\x23\x1d\x16\xd4\x1c\x59"
-                         "\x9c\x1a\x02\x55\xab\x3a\x97\x1d"
-                         "\xdf\xdd\xc7\x06\x51\xd7\x70\xae"
-                         "\x23\xc6\x8c\xf5\x1e\xa0\xe5\x82"
-                         "\xb8\xb2\xbf\x04\xa0\x32\x8e\x68"
-                         "\xeb\xaf\x6e\x2d\x94\x22\x2f\xce"
-                         "\x4c\xb5\x59\xe2\xa2\x2f\xa0\x98"
-                         "\x1a\x97\xc6\xd4\xb5\x00\x59\xf2"
-                         "\x84\x14\x72\xb1\x9a\x6e\xa3\x7f"
-                         "\xea\x20\xe7\xcb\x65\x77\x3a\xdf"
-                         "\xc8\x97\x67\x15\xc2\x2a\x27\xcc"
-                         "\x18\x55\xa1\x24\x0b\x24\x24\xaf"
-                         "\x5b\xec\x68\xb8\xc8\xf5\xba\x63"
-                         "\xff\xed\x89\xce\xd5\x3d\x88\xf3"
-                         "\x25\xef\x05\x7c\x3a\xef\xeb\xd8"
-                         "\x7a\x32\x0d\xd1\x1e\x58\x59\x99"
-                         "\x90\x25\xb5\x26\xb0\xe3\x2b\x6c"
-                         "\x4c\xa9\x8b\x84\x4f\x5e\x01\x50"
-                         "\x41\x30\x58\xc5\x62\x74\x52\x1d"
-                         "\x45\x24\x6a\x42\x64\x4f\x97\x1c"
-                         "\xa8\x66\xb5\x6d\x79\xd4\x0d\x48"
-                         "\xc5\x5f\xf3\x90\x32\xdd\xdd\xe1"
-                         "\xe4\xa9\x9f\xfc\xc3\x52\x5a\x46"
-                         "\xe4\x81\x84\x95\x36\x59\x7a\x6b"
-                         "\xaa\xb3\x60\xad\xce\x9f\x9f\x28"
-                         "\xe0\x01\x75\x22\xc4\x4e\xa9\x62"
-                         "\x5c\x62\x0d\x00\xcb\x13\xe8\x43"
-                         "\x72\xd4\x2d\x53\x46\xb5\xd1\x16"
-                         "\x22\x18\xdf\x34\x33\xf5\xd6\x1c"
-                         "\xb8\x79\x78\x97\x94\xff\x72\x13"
-                         "\x4c\x27\xfc\xcb\xbf\x01\x53\xa6"
-                         "\xb4\x50\x6e\xde\xdf\xb5\x43\xa4"
-                         "\x59\xdf\x52\xf9\x7c\xe0\x11\x6f"
-                         "\x2d\x14\x8e\x24\x61\x2c\xe1\x17"
-                         "\xcc\xce\x51\x0c\x19\x8a\x82\x30"
-                         "\x94\xd5\x3d\x6a\x53\x06\x5e\xbd"
-                         "\xb7\xeb\xfa\xfd\x27\x51\xde\x85"
-                         "\x1e\x86\x53\x11\x53\x94\x00\xee"
-                         "\x2b\x8c\x08\x2a\xbf\xdd\xae\x11"
-                         "\xcb\x1e\xa2\x07\x9a\x80\xcf\x62"
-                         "\x9b\x09\xdc\x95\x3c\x96\x8e\xb1"
-                         "\x09\xbd\xe4\xeb\xdb\xca\x70\x7a"
-                         "\x9e\xfa\x31\x18\x45\x3c\x21\x33"
-                         "\xb0\xb3\x2b\xea\xf3\x71\x2d\xe1"
-                         "\x03\xad\x1b\x48\xd4\x67\x27\xf0"
-                         "\x62\xe4\x3d\xfb\x9b\x08\x76\xe7"
-                         "\xdd\x2b\x01\x39\x04\x5a\x58\x7a"
-                         "\xf7\x11\x90\xec\xbd\x51\x5c\x32"
-                         "\x6b\xd7\x35\x39\x02\x6b\xf2\xa6"
-                         "\xd0\x0d\x07\xe1\x06\xc4\x5b\x7d"
-                         "\xe4\x6a\xd7\xee\x15\x1f\x83\xb4"
-                         "\xa3\xa7\x5e\xc3\x90\xb7\xef\xd3"
-                         "\xb7\x4f\xf8\x92\x4c\xb7\x3c\x29"
-                         "\xcd\x7e\x2b\x5d\x43\xea\x42\xe7"
-                         "\x74\x3f\x7d\x58\x88\x75\xde\x3e",
-               .rlen   = 512,
-       }
-};
-
-static struct cipher_testvec aes_lrw_dec_tv_template[] = {
-       /* from http://grouper.ieee.org/groups/1619/email/pdf00017.pdf */
-       /* same as enc vectors with input and result reversed */
-       { /* LRW-32-AES 1 */
-               .key    = "\x45\x62\xac\x25\xf8\x28\x17\x6d"
-                         "\x4c\x26\x84\x14\xb5\x68\x01\x85"
-                         "\x25\x8e\x2a\x05\xe7\x3e\x9d\x03"
-                         "\xee\x5a\x83\x0c\xcc\x09\x4c\x87",
-               .klen   = 32,
-               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x01",
-               .input  = "\xf1\xb2\x73\xcd\x65\xa3\xdf\x5f"
-                         "\xe9\x5d\x48\x92\x54\x63\x4e\xb8",
-               .ilen   = 16,
-               .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
-                         "\x38\x39\x41\x42\x43\x44\x45\x46",
-               .rlen   = 16,
-       }, { /* LRW-32-AES 2 */
-               .key    = "\x59\x70\x47\x14\xf5\x57\x47\x8c"
-                         "\xd7\x79\xe8\x0f\x54\x88\x79\x44"
-                         "\x0d\x48\xf0\xb7\xb1\x5a\x53\xea"
-                         "\x1c\xaa\x6b\x29\xc2\xca\xfb\xaf",
-               .klen   = 32,
-               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x02",
-               .input  = "\x00\xc8\x2b\xae\x95\xbb\xcd\xe5"
-                         "\x27\x4f\x07\x69\xb2\x60\xe1\x36",
-               .ilen   = 16,
-               .result  = "\x30\x31\x32\x33\x34\x35\x36\x37"
-                          "\x38\x39\x41\x42\x43\x44\x45\x46",
-               .rlen   = 16,
-       }, { /* LRW-32-AES 3 */
-               .key    = "\xd8\x2a\x91\x34\xb2\x6a\x56\x50"
-                         "\x30\xfe\x69\xe2\x37\x7f\x98\x47"
-                         "\xcd\xf9\x0b\x16\x0c\x64\x8f\xb6"
-                         "\xb0\x0d\x0d\x1b\xae\x85\x87\x1f",
-               .klen   = 32,
-               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x02\x00\x00\x00\x00",
-               .input  = "\x76\x32\x21\x83\xed\x8f\xf1\x82"
-                         "\xf9\x59\x62\x03\x69\x0e\x5e\x01",
-               .ilen   = 16,
-               .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
-                         "\x38\x39\x41\x42\x43\x44\x45\x46",
-               .rlen   = 16,
-       }, { /* LRW-32-AES 4 */
-               .key    = "\x0f\x6a\xef\xf8\xd3\xd2\xbb\x15"
-                         "\x25\x83\xf7\x3c\x1f\x01\x28\x74"
-                         "\xca\xc6\xbc\x35\x4d\x4a\x65\x54"
-                         "\x90\xae\x61\xcf\x7b\xae\xbd\xcc"
-                         "\xad\xe4\x94\xc5\x4a\x29\xae\x70",
-               .klen   = 40,
-               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x01",
-               .input  = "\x9c\x0f\x15\x2f\x55\xa2\xd8\xf0"
-                         "\xd6\x7b\x8f\x9e\x28\x22\xbc\x41",
-               .ilen   = 16,
-               .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
-                         "\x38\x39\x41\x42\x43\x44\x45\x46",
-               .rlen   = 16,
-       }, { /* LRW-32-AES 5 */
-               .key    = "\x8a\xd4\xee\x10\x2f\xbd\x81\xff"
-                         "\xf8\x86\xce\xac\x93\xc5\xad\xc6"
-                         "\xa0\x19\x07\xc0\x9d\xf7\xbb\xdd"
-                         "\x52\x13\xb2\xb7\xf0\xff\x11\xd8"
-                         "\xd6\x08\xd0\xcd\x2e\xb1\x17\x6f",
-               .klen   = 40,
-               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x02\x00\x00\x00\x00",
-               .input  = "\xd4\x27\x6a\x7f\x14\x91\x3d\x65"
-                         "\xc8\x60\x48\x02\x87\xe3\x34\x06",
-               .ilen   = 16,
-               .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
-                         "\x38\x39\x41\x42\x43\x44\x45\x46",
-               .rlen   = 16,
-       }, { /* LRW-32-AES 6 */
-               .key    = "\xf8\xd4\x76\xff\xd6\x46\xee\x6c"
-                         "\x23\x84\xcb\x1c\x77\xd6\x19\x5d"
-                         "\xfe\xf1\xa9\xf3\x7b\xbc\x8d\x21"
-                         "\xa7\x9c\x21\xf8\xcb\x90\x02\x89"
-                         "\xa8\x45\x34\x8e\xc8\xc5\xb5\xf1"
-                         "\x26\xf5\x0e\x76\xfe\xfd\x1b\x1e",
-               .klen   = 48,
-               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x01",
-               .input  = "\xbd\x06\xb8\xe1\xdb\x98\x89\x9e"
-                         "\xc4\x98\xe4\x91\xcf\x1c\x70\x2b",
-               .ilen   = 16,
-               .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
-                         "\x38\x39\x41\x42\x43\x44\x45\x46",
-               .rlen   = 16,
-       }, { /* LRW-32-AES 7 */
-               .key    = "\xfb\x76\x15\xb2\x3d\x80\x89\x1d"
-                         "\xd4\x70\x98\x0b\xc7\x95\x84\xc8"
-                         "\xb2\xfb\x64\xce\x60\x97\x87\x8d"
-                         "\x17\xfc\xe4\x5a\x49\xe8\x30\xb7"
-                         "\x6e\x78\x17\xe7\x2d\x5e\x12\xd4"
-                         "\x60\x64\x04\x7a\xf1\x2f\x9e\x0c",
-               .klen   = 48,
-               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x02\x00\x00\x00\x00",
-               .input  = "\x5b\x90\x8e\xc1\xab\xdd\x67\x5f"
-                         "\x3d\x69\x8a\x95\x53\xc8\x9c\xe5",
-               .ilen   = 16,
-               .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
-                         "\x38\x39\x41\x42\x43\x44\x45\x46",
-               .rlen   = 16,
-       }, {
-/* http://www.mail-archive.com/stds-p1619@listserv.ieee.org/msg00173.html */
-               .key    = "\xf8\xd4\x76\xff\xd6\x46\xee\x6c"
-                         "\x23\x84\xcb\x1c\x77\xd6\x19\x5d"
-                         "\xfe\xf1\xa9\xf3\x7b\xbc\x8d\x21"
-                         "\xa7\x9c\x21\xf8\xcb\x90\x02\x89"
-                         "\xa8\x45\x34\x8e\xc8\xc5\xb5\xf1"
-                         "\x26\xf5\x0e\x76\xfe\xfd\x1b\x1e",
-               .klen   = 48,
-               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x01",
-               .input  = "\x1a\x1d\xa9\x30\xad\xf9\x2f\x9b"
-                         "\xb6\x1d\xae\xef\xf0\x2f\xf8\x5a"
-                         "\x39\x3c\xbf\x2a\xb2\x45\xb2\x23"
-                         "\x1b\x63\x3c\xcf\xaa\xbe\xcf\x4e"
-                         "\xfa\xe8\x29\xc2\x20\x68\x2b\x3c"
-                         "\x2e\x8b\xf7\x6e\x25\xbd\xe3\x3d"
-                         "\x66\x27\xd6\xaf\xd6\x64\x3e\xe3"
-                         "\xe8\x58\x46\x97\x39\x51\x07\xde"
-                         "\xcb\x37\xbc\xa9\xc0\x5f\x75\xc3"
-                         "\x0e\x84\x23\x1d\x16\xd4\x1c\x59"
-                         "\x9c\x1a\x02\x55\xab\x3a\x97\x1d"
-                         "\xdf\xdd\xc7\x06\x51\xd7\x70\xae"
-                         "\x23\xc6\x8c\xf5\x1e\xa0\xe5\x82"
-                         "\xb8\xb2\xbf\x04\xa0\x32\x8e\x68"
-                         "\xeb\xaf\x6e\x2d\x94\x22\x2f\xce"
-                         "\x4c\xb5\x59\xe2\xa2\x2f\xa0\x98"
-                         "\x1a\x97\xc6\xd4\xb5\x00\x59\xf2"
-                         "\x84\x14\x72\xb1\x9a\x6e\xa3\x7f"
-                         "\xea\x20\xe7\xcb\x65\x77\x3a\xdf"
-                         "\xc8\x97\x67\x15\xc2\x2a\x27\xcc"
-                         "\x18\x55\xa1\x24\x0b\x24\x24\xaf"
-                         "\x5b\xec\x68\xb8\xc8\xf5\xba\x63"
-                         "\xff\xed\x89\xce\xd5\x3d\x88\xf3"
-                         "\x25\xef\x05\x7c\x3a\xef\xeb\xd8"
-                         "\x7a\x32\x0d\xd1\x1e\x58\x59\x99"
-                         "\x90\x25\xb5\x26\xb0\xe3\x2b\x6c"
-                         "\x4c\xa9\x8b\x84\x4f\x5e\x01\x50"
-                         "\x41\x30\x58\xc5\x62\x74\x52\x1d"
-                         "\x45\x24\x6a\x42\x64\x4f\x97\x1c"
-                         "\xa8\x66\xb5\x6d\x79\xd4\x0d\x48"
-                         "\xc5\x5f\xf3\x90\x32\xdd\xdd\xe1"
-                         "\xe4\xa9\x9f\xfc\xc3\x52\x5a\x46"
-                         "\xe4\x81\x84\x95\x36\x59\x7a\x6b"
-                         "\xaa\xb3\x60\xad\xce\x9f\x9f\x28"
-                         "\xe0\x01\x75\x22\xc4\x4e\xa9\x62"
-                         "\x5c\x62\x0d\x00\xcb\x13\xe8\x43"
-                         "\x72\xd4\x2d\x53\x46\xb5\xd1\x16"
-                         "\x22\x18\xdf\x34\x33\xf5\xd6\x1c"
-                         "\xb8\x79\x78\x97\x94\xff\x72\x13"
-                         "\x4c\x27\xfc\xcb\xbf\x01\x53\xa6"
-                         "\xb4\x50\x6e\xde\xdf\xb5\x43\xa4"
-                         "\x59\xdf\x52\xf9\x7c\xe0\x11\x6f"
-                         "\x2d\x14\x8e\x24\x61\x2c\xe1\x17"
-                         "\xcc\xce\x51\x0c\x19\x8a\x82\x30"
-                         "\x94\xd5\x3d\x6a\x53\x06\x5e\xbd"
-                         "\xb7\xeb\xfa\xfd\x27\x51\xde\x85"
-                         "\x1e\x86\x53\x11\x53\x94\x00\xee"
-                         "\x2b\x8c\x08\x2a\xbf\xdd\xae\x11"
-                         "\xcb\x1e\xa2\x07\x9a\x80\xcf\x62"
-                         "\x9b\x09\xdc\x95\x3c\x96\x8e\xb1"
-                         "\x09\xbd\xe4\xeb\xdb\xca\x70\x7a"
-                         "\x9e\xfa\x31\x18\x45\x3c\x21\x33"
-                         "\xb0\xb3\x2b\xea\xf3\x71\x2d\xe1"
-                         "\x03\xad\x1b\x48\xd4\x67\x27\xf0"
-                         "\x62\xe4\x3d\xfb\x9b\x08\x76\xe7"
-                         "\xdd\x2b\x01\x39\x04\x5a\x58\x7a"
-                         "\xf7\x11\x90\xec\xbd\x51\x5c\x32"
-                         "\x6b\xd7\x35\x39\x02\x6b\xf2\xa6"
-                         "\xd0\x0d\x07\xe1\x06\xc4\x5b\x7d"
-                         "\xe4\x6a\xd7\xee\x15\x1f\x83\xb4"
-                         "\xa3\xa7\x5e\xc3\x90\xb7\xef\xd3"
-                         "\xb7\x4f\xf8\x92\x4c\xb7\x3c\x29"
-                         "\xcd\x7e\x2b\x5d\x43\xea\x42\xe7"
-                         "\x74\x3f\x7d\x58\x88\x75\xde\x3e",
-               .ilen   = 512,
-               .result = "\x05\x11\xb7\x18\xab\xc6\x2d\xac"
-                         "\x70\x5d\xf6\x22\x94\xcd\xe5\x6c"
-                         "\x17\x6b\xf6\x1c\xf0\xf3\x6e\xf8"
-                         "\x50\x38\x1f\x71\x49\xb6\x57\xd6"
-                         "\x8f\xcb\x8d\x6b\xe3\xa6\x29\x90"
-                         "\xfe\x2a\x62\x82\xae\x6d\x8b\xf6"
-                         "\xad\x1e\x9e\x20\x5f\x38\xbe\x04"
-                         "\xda\x10\x8e\xed\xa2\xa4\x87\xab"
-                         "\xda\x6b\xb4\x0c\x75\xba\xd3\x7c"
-                         "\xc9\xac\x42\x31\x95\x7c\xc9\x04"
-                         "\xeb\xd5\x6e\x32\x69\x8a\xdb\xa6"
-                         "\x15\xd7\x3f\x4f\x2f\x66\x69\x03"
-                         "\x9c\x1f\x54\x0f\xde\x1f\xf3\x65"
-                         "\x4c\x96\x12\xed\x7c\x92\x03\x01"
-                         "\x6f\xbc\x35\x93\xac\xf1\x27\xf1"
-                         "\xb4\x96\x82\x5a\x5f\xb0\xa0\x50"
-                         "\x89\xa4\x8e\x66\x44\x85\xcc\xfd"
-                         "\x33\x14\x70\xe3\x96\xb2\xc3\xd3"
-                         "\xbb\x54\x5a\x1a\xf9\x74\xa2\xc5"
-                         "\x2d\x64\x75\xdd\xb4\x54\xe6\x74"
-                         "\x8c\xd3\x9d\x9e\x86\xab\x51\x53"
-                         "\xb7\x93\x3e\x6f\xd0\x4e\x2c\x40"
-                         "\xf6\xa8\x2e\x3e\x9d\xf4\x66\xa5"
-                         "\x76\x12\x73\x44\x1a\x56\xd7\x72"
-                         "\x88\xcd\x21\x8c\x4c\x0f\xfe\xda"
-                         "\x95\xe0\x3a\xa6\xa5\x84\x46\xcd"
-                         "\xd5\x3e\x9d\x3a\xe2\x67\xe6\x60"
-                         "\x1a\xe2\x70\x85\x58\xc2\x1b\x09"
-                         "\xe1\xd7\x2c\xca\xad\xa8\x8f\xf9"
-                         "\xac\xb3\x0e\xdb\xca\x2e\xe2\xb8"
-                         "\x51\x71\xd9\x3c\x6c\xf1\x56\xf8"
-                         "\xea\x9c\xf1\xfb\x0c\xe6\xb7\x10"
-                         "\x1c\xf8\xa9\x7c\xe8\x53\x35\xc1"
-                         "\x90\x3e\x76\x4a\x74\xa4\x21\x2c"
-                         "\xf6\x2c\x4e\x0f\x94\x3a\x88\x2e"
-                         "\x41\x09\x6a\x33\x7d\xf6\xdd\x3f"
-                         "\x8d\x23\x31\x74\x84\xeb\x88\x6e"
-                         "\xcc\xb9\xbc\x22\x83\x19\x07\x22"
-                         "\xa5\x2d\xdf\xa5\xf3\x80\x85\x78"
-                         "\x84\x39\x6a\x6d\x6a\x99\x4f\xa5"
-                         "\x15\xfe\x46\xb0\xe4\x6c\xa5\x41"
-                         "\x3c\xce\x8f\x42\x60\x71\xa7\x75"
-                         "\x08\x40\x65\x8a\x82\xbf\xf5\x43"
-                         "\x71\x96\xa9\x4d\x44\x8a\x20\xbe"
-                         "\xfa\x4d\xbb\xc0\x7d\x31\x96\x65"
-                         "\xe7\x75\xe5\x3e\xfd\x92\x3b\xc9"
-                         "\x55\xbb\x16\x7e\xf7\xc2\x8c\xa4"
-                         "\x40\x1d\xe5\xef\x0e\xdf\xe4\x9a"
-                         "\x62\x73\x65\xfd\x46\x63\x25\x3d"
-                         "\x2b\xaf\xe5\x64\xfe\xa5\x5c\xcf"
-                         "\x24\xf3\xb4\xac\x64\xba\xdf\x4b"
-                         "\xc6\x96\x7d\x81\x2d\x8d\x97\xf7"
-                         "\xc5\x68\x77\x84\x32\x2b\xcc\x85"
-                         "\x74\x96\xf0\x12\x77\x61\xb9\xeb"
-                         "\x71\xaa\x82\xcb\x1c\xdb\x89\xc8"
-                         "\xc6\xb5\xe3\x5c\x7d\x39\x07\x24"
-                         "\xda\x39\x87\x45\xc0\x2b\xbb\x01"
-                         "\xac\xbc\x2a\x5c\x7f\xfc\xe8\xce"
-                         "\x6d\x9c\x6f\xed\xd3\xc1\xa1\xd6"
-                         "\xc5\x55\xa9\x66\x2f\xe1\xc8\x32"
-                         "\xa6\x5d\xa4\x3a\x98\x73\xe8\x45"
-                         "\xa4\xc7\xa8\xb4\xf6\x13\x03\xf6"
-                         "\xe9\x2e\xc4\x29\x0f\x84\xdb\xc4"
-                         "\x21\xc4\xc2\x75\x67\x89\x37\x0a",
-               .rlen   = 512,
-       }
-};
-
-static struct cipher_testvec aes_xts_enc_tv_template[] = {
-       /* http://grouper.ieee.org/groups/1619/email/pdf00086.pdf */
-       { /* XTS-AES 1 */
-               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .klen   = 32,
-               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .ilen   = 32,
-               .result = "\x91\x7c\xf6\x9e\xbd\x68\xb2\xec"
-                         "\x9b\x9f\xe9\xa3\xea\xdd\xa6\x92"
-                         "\xcd\x43\xd2\xf5\x95\x98\xed\x85"
-                         "\x8c\x02\xc2\x65\x2f\xbf\x92\x2e",
-               .rlen   = 32,
-       }, { /* XTS-AES 2 */
-               .key    = "\x11\x11\x11\x11\x11\x11\x11\x11"
-                         "\x11\x11\x11\x11\x11\x11\x11\x11"
-                         "\x22\x22\x22\x22\x22\x22\x22\x22"
-                         "\x22\x22\x22\x22\x22\x22\x22\x22",
-               .klen   = 32,
-               .iv     = "\x33\x33\x33\x33\x33\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .input  = "\x44\x44\x44\x44\x44\x44\x44\x44"
-                         "\x44\x44\x44\x44\x44\x44\x44\x44"
-                         "\x44\x44\x44\x44\x44\x44\x44\x44"
-                         "\x44\x44\x44\x44\x44\x44\x44\x44",
-               .ilen   = 32,
-               .result = "\xc4\x54\x18\x5e\x6a\x16\x93\x6e"
-                         "\x39\x33\x40\x38\xac\xef\x83\x8b"
-                         "\xfb\x18\x6f\xff\x74\x80\xad\xc4"
-                         "\x28\x93\x82\xec\xd6\xd3\x94\xf0",
-               .rlen   = 32,
-       }, { /* XTS-AES 3 */
-               .key    = "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8"
-                         "\xf7\xf6\xf5\xf4\xf3\xf2\xf1\xf0"
-                         "\x22\x22\x22\x22\x22\x22\x22\x22"
-                         "\x22\x22\x22\x22\x22\x22\x22\x22",
-               .klen   = 32,
-               .iv     = "\x33\x33\x33\x33\x33\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .input  = "\x44\x44\x44\x44\x44\x44\x44\x44"
-                         "\x44\x44\x44\x44\x44\x44\x44\x44"
-                         "\x44\x44\x44\x44\x44\x44\x44\x44"
-                         "\x44\x44\x44\x44\x44\x44\x44\x44",
-               .ilen   = 32,
-               .result = "\xaf\x85\x33\x6b\x59\x7a\xfc\x1a"
-                         "\x90\x0b\x2e\xb2\x1e\xc9\x49\xd2"
-                         "\x92\xdf\x4c\x04\x7e\x0b\x21\x53"
-                         "\x21\x86\xa5\x97\x1a\x22\x7a\x89",
-               .rlen   = 32,
-       }, { /* XTS-AES 4 */
-               .key    = "\x27\x18\x28\x18\x28\x45\x90\x45"
-                         "\x23\x53\x60\x28\x74\x71\x35\x26"
-                         "\x31\x41\x59\x26\x53\x58\x97\x93"
-                         "\x23\x84\x62\x64\x33\x83\x27\x95",
-               .klen   = 32,
-               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                         "\x10\x11\x12\x13\x14\x15\x16\x17"
-                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
-                         "\x20\x21\x22\x23\x24\x25\x26\x27"
-                         "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
-                         "\x30\x31\x32\x33\x34\x35\x36\x37"
-                         "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
-                         "\x40\x41\x42\x43\x44\x45\x46\x47"
-                         "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
-                         "\x50\x51\x52\x53\x54\x55\x56\x57"
-                         "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
-                         "\x60\x61\x62\x63\x64\x65\x66\x67"
-                         "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
-                         "\x70\x71\x72\x73\x74\x75\x76\x77"
-                         "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
-                         "\x80\x81\x82\x83\x84\x85\x86\x87"
-                         "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
-                         "\x90\x91\x92\x93\x94\x95\x96\x97"
-                         "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
-                         "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
-                         "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
-                         "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
-                         "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
-                         "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
-                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
-                         "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
-                         "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
-                         "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
-                         "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
-                         "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
-                         "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
-                         "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                         "\x10\x11\x12\x13\x14\x15\x16\x17"
-                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
-                         "\x20\x21\x22\x23\x24\x25\x26\x27"
-                         "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
-                         "\x30\x31\x32\x33\x34\x35\x36\x37"
-                         "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
-                         "\x40\x41\x42\x43\x44\x45\x46\x47"
-                         "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
-                         "\x50\x51\x52\x53\x54\x55\x56\x57"
-                         "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
-                         "\x60\x61\x62\x63\x64\x65\x66\x67"
-                         "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
-                         "\x70\x71\x72\x73\x74\x75\x76\x77"
-                         "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
-                         "\x80\x81\x82\x83\x84\x85\x86\x87"
-                         "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
-                         "\x90\x91\x92\x93\x94\x95\x96\x97"
-                         "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
-                         "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
-                         "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
-                         "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
-                         "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
-                         "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
-                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
-                         "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
-                         "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
-                         "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
-                         "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
-                         "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
-                         "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
-               .ilen   = 512,
-               .result = "\x27\xa7\x47\x9b\xef\xa1\xd4\x76"
-                         "\x48\x9f\x30\x8c\xd4\xcf\xa6\xe2"
-                         "\xa9\x6e\x4b\xbe\x32\x08\xff\x25"
-                         "\x28\x7d\xd3\x81\x96\x16\xe8\x9c"
-                         "\xc7\x8c\xf7\xf5\xe5\x43\x44\x5f"
-                         "\x83\x33\xd8\xfa\x7f\x56\x00\x00"
-                         "\x05\x27\x9f\xa5\xd8\xb5\xe4\xad"
-                         "\x40\xe7\x36\xdd\xb4\xd3\x54\x12"
-                         "\x32\x80\x63\xfd\x2a\xab\x53\xe5"
-                         "\xea\x1e\x0a\x9f\x33\x25\x00\xa5"
-                         "\xdf\x94\x87\xd0\x7a\x5c\x92\xcc"
-                         "\x51\x2c\x88\x66\xc7\xe8\x60\xce"
-                         "\x93\xfd\xf1\x66\xa2\x49\x12\xb4"
-                         "\x22\x97\x61\x46\xae\x20\xce\x84"
-                         "\x6b\xb7\xdc\x9b\xa9\x4a\x76\x7a"
-                         "\xae\xf2\x0c\x0d\x61\xad\x02\x65"
-                         "\x5e\xa9\x2d\xc4\xc4\xe4\x1a\x89"
-                         "\x52\xc6\x51\xd3\x31\x74\xbe\x51"
-                         "\xa1\x0c\x42\x11\x10\xe6\xd8\x15"
-                         "\x88\xed\xe8\x21\x03\xa2\x52\xd8"
-                         "\xa7\x50\xe8\x76\x8d\xef\xff\xed"
-                         "\x91\x22\x81\x0a\xae\xb9\x9f\x91"
-                         "\x72\xaf\x82\xb6\x04\xdc\x4b\x8e"
-                         "\x51\xbc\xb0\x82\x35\xa6\xf4\x34"
-                         "\x13\x32\xe4\xca\x60\x48\x2a\x4b"
-                         "\xa1\xa0\x3b\x3e\x65\x00\x8f\xc5"
-                         "\xda\x76\xb7\x0b\xf1\x69\x0d\xb4"
-                         "\xea\xe2\x9c\x5f\x1b\xad\xd0\x3c"
-                         "\x5c\xcf\x2a\x55\xd7\x05\xdd\xcd"
-                         "\x86\xd4\x49\x51\x1c\xeb\x7e\xc3"
-                         "\x0b\xf1\x2b\x1f\xa3\x5b\x91\x3f"
-                         "\x9f\x74\x7a\x8a\xfd\x1b\x13\x0e"
-                         "\x94\xbf\xf9\x4e\xff\xd0\x1a\x91"
-                         "\x73\x5c\xa1\x72\x6a\xcd\x0b\x19"
-                         "\x7c\x4e\x5b\x03\x39\x36\x97\xe1"
-                         "\x26\x82\x6f\xb6\xbb\xde\x8e\xcc"
-                         "\x1e\x08\x29\x85\x16\xe2\xc9\xed"
-                         "\x03\xff\x3c\x1b\x78\x60\xf6\xde"
-                         "\x76\xd4\xce\xcd\x94\xc8\x11\x98"
-                         "\x55\xef\x52\x97\xca\x67\xe9\xf3"
-                         "\xe7\xff\x72\xb1\xe9\x97\x85\xca"
-                         "\x0a\x7e\x77\x20\xc5\xb3\x6d\xc6"
-                         "\xd7\x2c\xac\x95\x74\xc8\xcb\xbc"
-                         "\x2f\x80\x1e\x23\xe5\x6f\xd3\x44"
-                         "\xb0\x7f\x22\x15\x4b\xeb\xa0\xf0"
-                         "\x8c\xe8\x89\x1e\x64\x3e\xd9\x95"
-                         "\xc9\x4d\x9a\x69\xc9\xf1\xb5\xf4"
-                         "\x99\x02\x7a\x78\x57\x2a\xee\xbd"
-                         "\x74\xd2\x0c\xc3\x98\x81\xc2\x13"
-                         "\xee\x77\x0b\x10\x10\xe4\xbe\xa7"
-                         "\x18\x84\x69\x77\xae\x11\x9f\x7a"
-                         "\x02\x3a\xb5\x8c\xca\x0a\xd7\x52"
-                         "\xaf\xe6\x56\xbb\x3c\x17\x25\x6a"
-                         "\x9f\x6e\x9b\xf1\x9f\xdd\x5a\x38"
-                         "\xfc\x82\xbb\xe8\x72\xc5\x53\x9e"
-                         "\xdb\x60\x9e\xf4\xf7\x9c\x20\x3e"
-                         "\xbb\x14\x0f\x2e\x58\x3c\xb2\xad"
-                         "\x15\xb4\xaa\x5b\x65\x50\x16\xa8"
-                         "\x44\x92\x77\xdb\xd4\x77\xef\x2c"
-                         "\x8d\x6c\x01\x7d\xb7\x38\xb1\x8d"
-                         "\xeb\x4a\x42\x7d\x19\x23\xce\x3f"
-                         "\xf2\x62\x73\x57\x79\xa4\x18\xf2"
-                         "\x0a\x28\x2d\xf9\x20\x14\x7b\xea"
-                         "\xbe\x42\x1e\xe5\x31\x9d\x05\x68",
-               .rlen   = 512,
-       }
-};
-
-static struct cipher_testvec aes_xts_dec_tv_template[] = {
-       /* http://grouper.ieee.org/groups/1619/email/pdf00086.pdf */
-       { /* XTS-AES 1 */
-               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .klen   = 32,
-               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .input = "\x91\x7c\xf6\x9e\xbd\x68\xb2\xec"
-                        "\x9b\x9f\xe9\xa3\xea\xdd\xa6\x92"
-                        "\xcd\x43\xd2\xf5\x95\x98\xed\x85"
-                        "\x8c\x02\xc2\x65\x2f\xbf\x92\x2e",
-               .ilen   = 32,
-               .result  = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                          "\x00\x00\x00\x00\x00\x00\x00\x00"
-                          "\x00\x00\x00\x00\x00\x00\x00\x00"
-                          "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .rlen   = 32,
-       }, { /* XTS-AES 2 */
-               .key    = "\x11\x11\x11\x11\x11\x11\x11\x11"
-                         "\x11\x11\x11\x11\x11\x11\x11\x11"
-                         "\x22\x22\x22\x22\x22\x22\x22\x22"
-                         "\x22\x22\x22\x22\x22\x22\x22\x22",
-               .klen   = 32,
-               .iv     = "\x33\x33\x33\x33\x33\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .input  = "\xc4\x54\x18\x5e\x6a\x16\x93\x6e"
-                         "\x39\x33\x40\x38\xac\xef\x83\x8b"
-                         "\xfb\x18\x6f\xff\x74\x80\xad\xc4"
-                         "\x28\x93\x82\xec\xd6\xd3\x94\xf0",
-               .ilen   = 32,
-               .result = "\x44\x44\x44\x44\x44\x44\x44\x44"
-                         "\x44\x44\x44\x44\x44\x44\x44\x44"
-                         "\x44\x44\x44\x44\x44\x44\x44\x44"
-                         "\x44\x44\x44\x44\x44\x44\x44\x44",
-               .rlen   = 32,
-       }, { /* XTS-AES 3 */
-               .key    = "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8"
-                         "\xf7\xf6\xf5\xf4\xf3\xf2\xf1\xf0"
-                         "\x22\x22\x22\x22\x22\x22\x22\x22"
-                         "\x22\x22\x22\x22\x22\x22\x22\x22",
-               .klen   = 32,
-               .iv     = "\x33\x33\x33\x33\x33\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .input = "\xaf\x85\x33\x6b\x59\x7a\xfc\x1a"
-                         "\x90\x0b\x2e\xb2\x1e\xc9\x49\xd2"
-                         "\x92\xdf\x4c\x04\x7e\x0b\x21\x53"
-                         "\x21\x86\xa5\x97\x1a\x22\x7a\x89",
-               .ilen   = 32,
-               .result  = "\x44\x44\x44\x44\x44\x44\x44\x44"
-                         "\x44\x44\x44\x44\x44\x44\x44\x44"
-                         "\x44\x44\x44\x44\x44\x44\x44\x44"
-                         "\x44\x44\x44\x44\x44\x44\x44\x44",
-               .rlen   = 32,
-       }, { /* XTS-AES 4 */
-               .key    = "\x27\x18\x28\x18\x28\x45\x90\x45"
-                         "\x23\x53\x60\x28\x74\x71\x35\x26"
-                         "\x31\x41\x59\x26\x53\x58\x97\x93"
-                         "\x23\x84\x62\x64\x33\x83\x27\x95",
-               .klen   = 32,
-               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .input  = "\x27\xa7\x47\x9b\xef\xa1\xd4\x76"
-                         "\x48\x9f\x30\x8c\xd4\xcf\xa6\xe2"
-                         "\xa9\x6e\x4b\xbe\x32\x08\xff\x25"
-                         "\x28\x7d\xd3\x81\x96\x16\xe8\x9c"
-                         "\xc7\x8c\xf7\xf5\xe5\x43\x44\x5f"
-                         "\x83\x33\xd8\xfa\x7f\x56\x00\x00"
-                         "\x05\x27\x9f\xa5\xd8\xb5\xe4\xad"
-                         "\x40\xe7\x36\xdd\xb4\xd3\x54\x12"
-                         "\x32\x80\x63\xfd\x2a\xab\x53\xe5"
-                         "\xea\x1e\x0a\x9f\x33\x25\x00\xa5"
-                         "\xdf\x94\x87\xd0\x7a\x5c\x92\xcc"
-                         "\x51\x2c\x88\x66\xc7\xe8\x60\xce"
-                         "\x93\xfd\xf1\x66\xa2\x49\x12\xb4"
-                         "\x22\x97\x61\x46\xae\x20\xce\x84"
-                         "\x6b\xb7\xdc\x9b\xa9\x4a\x76\x7a"
-                         "\xae\xf2\x0c\x0d\x61\xad\x02\x65"
-                         "\x5e\xa9\x2d\xc4\xc4\xe4\x1a\x89"
-                         "\x52\xc6\x51\xd3\x31\x74\xbe\x51"
-                         "\xa1\x0c\x42\x11\x10\xe6\xd8\x15"
-                         "\x88\xed\xe8\x21\x03\xa2\x52\xd8"
-                         "\xa7\x50\xe8\x76\x8d\xef\xff\xed"
-                         "\x91\x22\x81\x0a\xae\xb9\x9f\x91"
-                         "\x72\xaf\x82\xb6\x04\xdc\x4b\x8e"
-                         "\x51\xbc\xb0\x82\x35\xa6\xf4\x34"
-                         "\x13\x32\xe4\xca\x60\x48\x2a\x4b"
-                         "\xa1\xa0\x3b\x3e\x65\x00\x8f\xc5"
-                         "\xda\x76\xb7\x0b\xf1\x69\x0d\xb4"
-                         "\xea\xe2\x9c\x5f\x1b\xad\xd0\x3c"
-                         "\x5c\xcf\x2a\x55\xd7\x05\xdd\xcd"
-                         "\x86\xd4\x49\x51\x1c\xeb\x7e\xc3"
-                         "\x0b\xf1\x2b\x1f\xa3\x5b\x91\x3f"
-                         "\x9f\x74\x7a\x8a\xfd\x1b\x13\x0e"
-                         "\x94\xbf\xf9\x4e\xff\xd0\x1a\x91"
-                         "\x73\x5c\xa1\x72\x6a\xcd\x0b\x19"
-                         "\x7c\x4e\x5b\x03\x39\x36\x97\xe1"
-                         "\x26\x82\x6f\xb6\xbb\xde\x8e\xcc"
-                         "\x1e\x08\x29\x85\x16\xe2\xc9\xed"
-                         "\x03\xff\x3c\x1b\x78\x60\xf6\xde"
-                         "\x76\xd4\xce\xcd\x94\xc8\x11\x98"
-                         "\x55\xef\x52\x97\xca\x67\xe9\xf3"
-                         "\xe7\xff\x72\xb1\xe9\x97\x85\xca"
-                         "\x0a\x7e\x77\x20\xc5\xb3\x6d\xc6"
-                         "\xd7\x2c\xac\x95\x74\xc8\xcb\xbc"
-                         "\x2f\x80\x1e\x23\xe5\x6f\xd3\x44"
-                         "\xb0\x7f\x22\x15\x4b\xeb\xa0\xf0"
-                         "\x8c\xe8\x89\x1e\x64\x3e\xd9\x95"
-                         "\xc9\x4d\x9a\x69\xc9\xf1\xb5\xf4"
-                         "\x99\x02\x7a\x78\x57\x2a\xee\xbd"
-                         "\x74\xd2\x0c\xc3\x98\x81\xc2\x13"
-                         "\xee\x77\x0b\x10\x10\xe4\xbe\xa7"
-                         "\x18\x84\x69\x77\xae\x11\x9f\x7a"
-                         "\x02\x3a\xb5\x8c\xca\x0a\xd7\x52"
-                         "\xaf\xe6\x56\xbb\x3c\x17\x25\x6a"
-                         "\x9f\x6e\x9b\xf1\x9f\xdd\x5a\x38"
-                         "\xfc\x82\xbb\xe8\x72\xc5\x53\x9e"
-                         "\xdb\x60\x9e\xf4\xf7\x9c\x20\x3e"
-                         "\xbb\x14\x0f\x2e\x58\x3c\xb2\xad"
-                         "\x15\xb4\xaa\x5b\x65\x50\x16\xa8"
-                         "\x44\x92\x77\xdb\xd4\x77\xef\x2c"
-                         "\x8d\x6c\x01\x7d\xb7\x38\xb1\x8d"
-                         "\xeb\x4a\x42\x7d\x19\x23\xce\x3f"
-                         "\xf2\x62\x73\x57\x79\xa4\x18\xf2"
-                         "\x0a\x28\x2d\xf9\x20\x14\x7b\xea"
-                         "\xbe\x42\x1e\xe5\x31\x9d\x05\x68",
-               .ilen   = 512,
-               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                         "\x10\x11\x12\x13\x14\x15\x16\x17"
-                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
-                         "\x20\x21\x22\x23\x24\x25\x26\x27"
-                         "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
-                         "\x30\x31\x32\x33\x34\x35\x36\x37"
-                         "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
-                         "\x40\x41\x42\x43\x44\x45\x46\x47"
-                         "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
-                         "\x50\x51\x52\x53\x54\x55\x56\x57"
-                         "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
-                         "\x60\x61\x62\x63\x64\x65\x66\x67"
-                         "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
-                         "\x70\x71\x72\x73\x74\x75\x76\x77"
-                         "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
-                         "\x80\x81\x82\x83\x84\x85\x86\x87"
-                         "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
-                         "\x90\x91\x92\x93\x94\x95\x96\x97"
-                         "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
-                         "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
-                         "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
-                         "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
-                         "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
-                         "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
-                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
-                         "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
-                         "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
-                         "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
-                         "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
-                         "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
-                         "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
-                         "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                         "\x10\x11\x12\x13\x14\x15\x16\x17"
-                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
-                         "\x20\x21\x22\x23\x24\x25\x26\x27"
-                         "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
-                         "\x30\x31\x32\x33\x34\x35\x36\x37"
-                         "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
-                         "\x40\x41\x42\x43\x44\x45\x46\x47"
-                         "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
-                         "\x50\x51\x52\x53\x54\x55\x56\x57"
-                         "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
-                         "\x60\x61\x62\x63\x64\x65\x66\x67"
-                         "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
-                         "\x70\x71\x72\x73\x74\x75\x76\x77"
-                         "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
-                         "\x80\x81\x82\x83\x84\x85\x86\x87"
-                         "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
-                         "\x90\x91\x92\x93\x94\x95\x96\x97"
-                         "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
-                         "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
-                         "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
-                         "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
-                         "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
-                         "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
-                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
-                         "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
-                         "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
-                         "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
-                         "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
-                         "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
-                         "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
-               .rlen   = 512,
-       }
-};
-
-
-static struct cipher_testvec aes_ctr_enc_tv_template[] = {
-       { /* From RFC 3686 */
-               .key    = "\xae\x68\x52\xf8\x12\x10\x67\xcc"
-                         "\x4b\xf7\xa5\x76\x55\x77\xf3\x9e"
-                         "\x00\x00\x00\x30",
-               .klen   = 20,
-               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .input  = "Single block msg",
-               .ilen   = 16,
-               .result = "\xe4\x09\x5d\x4f\xb7\xa7\xb3\x79"
-                         "\x2d\x61\x75\xa3\x26\x13\x11\xb8",
-               .rlen   = 16,
-       }, {
-               .key    = "\x7e\x24\x06\x78\x17\xfa\xe0\xd7"
-                         "\x43\xd6\xce\x1f\x32\x53\x91\x63"
-                         "\x00\x6c\xb6\xdb",
-               .klen   = 20,
-               .iv     = "\xc0\x54\x3b\x59\xda\x48\xd9\x0b",
-               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                         "\x10\x11\x12\x13\x14\x15\x16\x17"
-                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
-               .ilen   = 32,
-               .result = "\x51\x04\xa1\x06\x16\x8a\x72\xd9"
-                         "\x79\x0d\x41\xee\x8e\xda\xd3\x88"
-                         "\xeb\x2e\x1e\xfc\x46\xda\x57\xc8"
-                         "\xfc\xe6\x30\xdf\x91\x41\xbe\x28",
-               .rlen   = 32,
-       }, {
-               .key    = "\x16\xaf\x5b\x14\x5f\xc9\xf5\x79"
-                         "\xc1\x75\xf9\x3e\x3b\xfb\x0e\xed"
-                         "\x86\x3d\x06\xcc\xfd\xb7\x85\x15"
-                         "\x00\x00\x00\x48",
-               .klen   = 28,
-               .iv     = "\x36\x73\x3c\x14\x7d\x6d\x93\xcb",
-               .input  = "Single block msg",
-               .ilen   = 16,
-               .result = "\x4b\x55\x38\x4f\xe2\x59\xc9\xc8"
-                         "\x4e\x79\x35\xa0\x03\xcb\xe9\x28",
-               .rlen   = 16,
-       }, {
-               .key    = "\x7c\x5c\xb2\x40\x1b\x3d\xc3\x3c"
-                         "\x19\xe7\x34\x08\x19\xe0\xf6\x9c"
-                         "\x67\x8c\x3d\xb8\xe6\xf6\xa9\x1a"
-                         "\x00\x96\xb0\x3b",
-               .klen   = 28,
-               .iv     = "\x02\x0c\x6e\xad\xc2\xcb\x50\x0d",
-               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                         "\x10\x11\x12\x13\x14\x15\x16\x17"
-                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
-               .ilen   = 32,
-               .result = "\x45\x32\x43\xfc\x60\x9b\x23\x32"
-                         "\x7e\xdf\xaa\xfa\x71\x31\xcd\x9f"
-                         "\x84\x90\x70\x1c\x5a\xd4\xa7\x9c"
-                         "\xfc\x1f\xe0\xff\x42\xf4\xfb\x00",
-               .rlen   = 32,
-       }, {
-               .key    = "\x77\x6b\xef\xf2\x85\x1d\xb0\x6f"
-                         "\x4c\x8a\x05\x42\xc8\x69\x6f\x6c"
-                         "\x6a\x81\xaf\x1e\xec\x96\xb4\xd3"
-                         "\x7f\xc1\xd6\x89\xe6\xc1\xc1\x04"
-                         "\x00\x00\x00\x60",
-               .klen   = 36,
-               .iv     = "\xdb\x56\x72\xc9\x7a\xa8\xf0\xb2",
-               .input  = "Single block msg",
-               .ilen   = 16,
-               .result = "\x14\x5a\xd0\x1d\xbf\x82\x4e\xc7"
-                         "\x56\x08\x63\xdc\x71\xe3\xe0\xc0",
-               .rlen   = 16,
-       }, {
-               .key    = "\xf6\xd6\x6d\x6b\xd5\x2d\x59\xbb"
-                         "\x07\x96\x36\x58\x79\xef\xf8\x86"
-                         "\xc6\x6d\xd5\x1a\x5b\x6a\x99\x74"
-                         "\x4b\x50\x59\x0c\x87\xa2\x38\x84"
-                         "\x00\xfa\xac\x24",
-               .klen   = 36,
-               .iv     = "\xc1\x58\x5e\xf1\x5a\x43\xd8\x75",
-               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                         "\x10\x11\x12\x13\x14\x15\x16\x17"
-                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
-               .ilen   = 32,
-               .result = "\xf0\x5e\x23\x1b\x38\x94\x61\x2c"
-                         "\x49\xee\x00\x0b\x80\x4e\xb2\xa9"
-                         "\xb8\x30\x6b\x50\x8f\x83\x9d\x6a"
-                         "\x55\x30\x83\x1d\x93\x44\xaf\x1c",
-               .rlen   = 32,
-       }, {
-       // generated using Crypto++
-               .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                       "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                       "\x10\x11\x12\x13\x14\x15\x16\x17"
-                       "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
-                       "\x00\x00\x00\x00",
-               .klen = 32 + 4,
-               .iv = "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .input =
-                       "\x00\x01\x02\x03\x04\x05\x06\x07"
-                       "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                       "\x10\x11\x12\x13\x14\x15\x16\x17"
-                       "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
-                       "\x20\x21\x22\x23\x24\x25\x26\x27"
-                       "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
-                       "\x30\x31\x32\x33\x34\x35\x36\x37"
-                       "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
-                       "\x40\x41\x42\x43\x44\x45\x46\x47"
-                       "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
-                       "\x50\x51\x52\x53\x54\x55\x56\x57"
-                       "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
-                       "\x60\x61\x62\x63\x64\x65\x66\x67"
-                       "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
-                       "\x70\x71\x72\x73\x74\x75\x76\x77"
-                       "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
-                       "\x80\x81\x82\x83\x84\x85\x86\x87"
-                       "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
-                       "\x90\x91\x92\x93\x94\x95\x96\x97"
-                       "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
-                       "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
-                       "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
-                       "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
-                       "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
-                       "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
-                       "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
-                       "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
-                       "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
-                       "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
-                       "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
-                       "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
-                       "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
-                       "\x00\x03\x06\x09\x0c\x0f\x12\x15"
-                       "\x18\x1b\x1e\x21\x24\x27\x2a\x2d"
-                       "\x30\x33\x36\x39\x3c\x3f\x42\x45"
-                       "\x48\x4b\x4e\x51\x54\x57\x5a\x5d"
-                       "\x60\x63\x66\x69\x6c\x6f\x72\x75"
-                       "\x78\x7b\x7e\x81\x84\x87\x8a\x8d"
-                       "\x90\x93\x96\x99\x9c\x9f\xa2\xa5"
-                       "\xa8\xab\xae\xb1\xb4\xb7\xba\xbd"
-                       "\xc0\xc3\xc6\xc9\xcc\xcf\xd2\xd5"
-                       "\xd8\xdb\xde\xe1\xe4\xe7\xea\xed"
-                       "\xf0\xf3\xf6\xf9\xfc\xff\x02\x05"
-                       "\x08\x0b\x0e\x11\x14\x17\x1a\x1d"
-                       "\x20\x23\x26\x29\x2c\x2f\x32\x35"
-                       "\x38\x3b\x3e\x41\x44\x47\x4a\x4d"
-                       "\x50\x53\x56\x59\x5c\x5f\x62\x65"
-                       "\x68\x6b\x6e\x71\x74\x77\x7a\x7d"
-                       "\x80\x83\x86\x89\x8c\x8f\x92\x95"
-                       "\x98\x9b\x9e\xa1\xa4\xa7\xaa\xad"
-                       "\xb0\xb3\xb6\xb9\xbc\xbf\xc2\xc5"
-                       "\xc8\xcb\xce\xd1\xd4\xd7\xda\xdd"
-                       "\xe0\xe3\xe6\xe9\xec\xef\xf2\xf5"
-                       "\xf8\xfb\xfe\x01\x04\x07\x0a\x0d"
-                       "\x10\x13\x16\x19\x1c\x1f\x22\x25"
-                       "\x28\x2b\x2e\x31\x34\x37\x3a\x3d"
-                       "\x40\x43\x46\x49\x4c\x4f\x52\x55"
-                       "\x58\x5b\x5e\x61\x64\x67\x6a\x6d"
-                       "\x70\x73\x76\x79\x7c\x7f\x82\x85"
-                       "\x88\x8b\x8e\x91\x94\x97\x9a\x9d"
-                       "\xa0\xa3\xa6\xa9\xac\xaf\xb2\xb5"
-                       "\xb8\xbb\xbe\xc1\xc4\xc7\xca\xcd"
-                       "\xd0\xd3\xd6\xd9\xdc\xdf\xe2\xe5"
-                       "\xe8\xeb\xee\xf1\xf4\xf7\xfa\xfd"
-                       "\x00\x05\x0a\x0f\x14\x19\x1e\x23"
-                       "\x28\x2d\x32\x37\x3c\x41\x46\x4b"
-                       "\x50\x55\x5a\x5f\x64\x69\x6e\x73"
-                       "\x78\x7d\x82\x87\x8c\x91\x96\x9b"
-                       "\xa0\xa5\xaa\xaf\xb4\xb9\xbe\xc3"
-                       "\xc8\xcd\xd2\xd7\xdc\xe1\xe6\xeb"
-                       "\xf0\xf5\xfa\xff\x04\x09\x0e\x13"
-                       "\x18\x1d\x22\x27\x2c\x31\x36\x3b"
-                       "\x40\x45\x4a\x4f\x54\x59\x5e\x63"
-                       "\x68\x6d\x72\x77\x7c\x81\x86\x8b"
-                       "\x90\x95\x9a\x9f\xa4\xa9\xae\xb3"
-                       "\xb8\xbd\xc2\xc7\xcc\xd1\xd6\xdb"
-                       "\xe0\xe5\xea\xef\xf4\xf9\xfe\x03"
-                       "\x08\x0d\x12\x17\x1c\x21\x26\x2b"
-                       "\x30\x35\x3a\x3f\x44\x49\x4e\x53"
-                       "\x58\x5d\x62\x67\x6c\x71\x76\x7b"
-                       "\x80\x85\x8a\x8f\x94\x99\x9e\xa3"
-                       "\xa8\xad\xb2\xb7\xbc\xc1\xc6\xcb"
-                       "\xd0\xd5\xda\xdf\xe4\xe9\xee\xf3"
-                       "\xf8\xfd\x02\x07\x0c\x11\x16\x1b"
-                       "\x20\x25\x2a\x2f\x34\x39\x3e\x43"
-                       "\x48\x4d\x52\x57\x5c\x61\x66\x6b"
-                       "\x70\x75\x7a\x7f\x84\x89\x8e\x93"
-                       "\x98\x9d\xa2\xa7\xac\xb1\xb6\xbb"
-                       "\xc0\xc5\xca\xcf\xd4\xd9\xde\xe3"
-                       "\xe8\xed\xf2\xf7\xfc\x01\x06\x0b"
-                       "\x10\x15\x1a\x1f\x24\x29\x2e\x33"
-                       "\x38\x3d\x42\x47\x4c\x51\x56\x5b"
-                       "\x60\x65\x6a\x6f\x74\x79\x7e\x83"
-                       "\x88\x8d\x92\x97\x9c\xa1\xa6\xab"
-                       "\xb0\xb5\xba\xbf\xc4\xc9\xce\xd3"
-                       "\xd8\xdd\xe2\xe7\xec\xf1\xf6\xfb"
-                       "\x00\x07\x0e\x15\x1c\x23\x2a\x31"
-                       "\x38\x3f\x46\x4d\x54\x5b\x62\x69"
-                       "\x70\x77\x7e\x85\x8c\x93\x9a\xa1"
-                       "\xa8\xaf\xb6\xbd\xc4\xcb\xd2\xd9"
-                       "\xe0\xe7\xee\xf5\xfc\x03\x0a\x11"
-                       "\x18\x1f\x26\x2d\x34\x3b\x42\x49"
-                       "\x50\x57\x5e\x65\x6c\x73\x7a\x81"
-                       "\x88\x8f\x96\x9d\xa4\xab\xb2\xb9"
-                       "\xc0\xc7\xce\xd5\xdc\xe3\xea\xf1"
-                       "\xf8\xff\x06\x0d\x14\x1b\x22\x29"
-                       "\x30\x37\x3e\x45\x4c\x53\x5a\x61"
-                       "\x68\x6f\x76\x7d\x84\x8b\x92\x99"
-                       "\xa0\xa7\xae\xb5\xbc\xc3\xca\xd1"
-                       "\xd8\xdf\xe6\xed\xf4\xfb\x02\x09"
-                       "\x10\x17\x1e\x25\x2c\x33\x3a\x41"
-                       "\x48\x4f\x56\x5d\x64\x6b\x72\x79"
-                       "\x80\x87\x8e\x95\x9c\xa3\xaa\xb1"
-                       "\xb8\xbf\xc6\xcd\xd4\xdb\xe2\xe9"
-                       "\xf0\xf7\xfe\x05\x0c\x13\x1a\x21"
-                       "\x28\x2f\x36\x3d\x44\x4b\x52\x59"
-                       "\x60\x67\x6e\x75\x7c\x83\x8a\x91"
-                       "\x98\x9f\xa6\xad\xb4\xbb\xc2\xc9"
-                       "\xd0\xd7\xde\xe5\xec\xf3\xfa\x01"
-                       "\x08\x0f\x16\x1d\x24\x2b\x32\x39"
-                       "\x40\x47\x4e\x55\x5c\x63\x6a\x71"
-                       "\x78\x7f\x86\x8d\x94\x9b\xa2\xa9"
-                       "\xb0\xb7\xbe\xc5\xcc\xd3\xda\xe1"
-                       "\xe8\xef\xf6\xfd\x04\x0b\x12\x19"
-                       "\x20\x27\x2e\x35\x3c\x43\x4a\x51"
-                       "\x58\x5f\x66\x6d\x74\x7b\x82\x89"
-                       "\x90\x97\x9e\xa5\xac\xb3\xba\xc1"
-                       "\xc8\xcf\xd6\xdd\xe4\xeb\xf2\xf9"
-                       "\x00\x09\x12\x1b\x24\x2d\x36\x3f"
-                       "\x48\x51\x5a\x63\x6c\x75\x7e\x87"
-                       "\x90\x99\xa2\xab\xb4\xbd\xc6\xcf"
-                       "\xd8\xe1\xea\xf3\xfc\x05\x0e\x17"
-                       "\x20\x29\x32\x3b\x44\x4d\x56\x5f"
-                       "\x68\x71\x7a\x83\x8c\x95\x9e\xa7"
-                       "\xb0\xb9\xc2\xcb\xd4\xdd\xe6\xef"
-                       "\xf8\x01\x0a\x13\x1c\x25\x2e\x37"
-                       "\x40\x49\x52\x5b\x64\x6d\x76\x7f"
-                       "\x88\x91\x9a\xa3\xac\xb5\xbe\xc7"
-                       "\xd0\xd9\xe2\xeb\xf4\xfd\x06\x0f"
-                       "\x18\x21\x2a\x33\x3c\x45\x4e\x57"
-                       "\x60\x69\x72\x7b\x84\x8d\x96\x9f"
-                       "\xa8\xb1\xba\xc3\xcc\xd5\xde\xe7"
-                       "\xf0\xf9\x02\x0b\x14\x1d\x26\x2f"
-                       "\x38\x41\x4a\x53\x5c\x65\x6e\x77"
-                       "\x80\x89\x92\x9b\xa4\xad\xb6\xbf"
-                       "\xc8\xd1\xda\xe3\xec\xf5\xfe\x07"
-                       "\x10\x19\x22\x2b\x34\x3d\x46\x4f"
-                       "\x58\x61\x6a\x73\x7c\x85\x8e\x97"
-                       "\xa0\xa9\xb2\xbb\xc4\xcd\xd6\xdf"
-                       "\xe8\xf1\xfa\x03\x0c\x15\x1e\x27"
-                       "\x30\x39\x42\x4b\x54\x5d\x66\x6f"
-                       "\x78\x81\x8a\x93\x9c\xa5\xae\xb7"
-                       "\xc0\xc9\xd2\xdb\xe4\xed\xf6\xff"
-                       "\x08\x11\x1a\x23\x2c\x35\x3e\x47"
-                       "\x50\x59\x62\x6b\x74\x7d\x86\x8f"
-                       "\x98\xa1\xaa\xb3\xbc\xc5\xce\xd7"
-                       "\xe0\xe9\xf2\xfb\x04\x0d\x16\x1f"
-                       "\x28\x31\x3a\x43\x4c\x55\x5e\x67"
-                       "\x70\x79\x82\x8b\x94\x9d\xa6\xaf"
-                       "\xb8\xc1\xca\xd3\xdc\xe5\xee\xf7"
-                       "\x00\x0b\x16\x21\x2c\x37\x42\x4d"
-                       "\x58\x63\x6e\x79\x84\x8f\x9a\xa5"
-                       "\xb0\xbb\xc6\xd1\xdc\xe7\xf2\xfd"
-                       "\x08\x13\x1e\x29\x34\x3f\x4a\x55"
-                       "\x60\x6b\x76\x81\x8c\x97\xa2\xad"
-                       "\xb8\xc3\xce\xd9\xe4\xef\xfa\x05"
-                       "\x10\x1b\x26\x31\x3c\x47\x52\x5d"
-                       "\x68\x73\x7e\x89\x94\x9f\xaa\xb5"
-                       "\xc0\xcb\xd6\xe1\xec\xf7\x02\x0d"
-                       "\x18\x23\x2e\x39\x44\x4f\x5a\x65"
-                       "\x70\x7b\x86\x91\x9c\xa7\xb2\xbd"
-                       "\xc8\xd3\xde\xe9\xf4\xff\x0a\x15"
-                       "\x20\x2b\x36\x41\x4c\x57\x62\x6d"
-                       "\x78\x83\x8e\x99\xa4\xaf\xba\xc5"
-                       "\xd0\xdb\xe6\xf1\xfc\x07\x12\x1d"
-                       "\x28\x33\x3e\x49\x54\x5f\x6a\x75"
-                       "\x80\x8b\x96\xa1\xac\xb7\xc2\xcd"
-                       "\xd8\xe3\xee\xf9\x04\x0f\x1a\x25"
-                       "\x30\x3b\x46\x51\x5c\x67\x72\x7d"
-                       "\x88\x93\x9e\xa9\xb4\xbf\xca\xd5"
-                       "\xe0\xeb\xf6\x01\x0c\x17\x22\x2d"
-                       "\x38\x43\x4e\x59\x64\x6f\x7a\x85"
-                       "\x90\x9b\xa6\xb1\xbc\xc7\xd2\xdd"
-                       "\xe8\xf3\xfe\x09\x14\x1f\x2a\x35"
-                       "\x40\x4b\x56\x61\x6c\x77\x82\x8d"
-                       "\x98\xa3\xae\xb9\xc4\xcf\xda\xe5"
-                       "\xf0\xfb\x06\x11\x1c\x27\x32\x3d"
-                       "\x48\x53\x5e\x69\x74\x7f\x8a\x95"
-                       "\xa0\xab\xb6\xc1\xcc\xd7\xe2\xed"
-                       "\xf8\x03\x0e\x19\x24\x2f\x3a\x45"
-                       "\x50\x5b\x66\x71\x7c\x87\x92\x9d"
-                       "\xa8\xb3\xbe\xc9\xd4\xdf\xea\xf5"
-                       "\x00\x0d\x1a\x27\x34\x41\x4e\x5b"
-                       "\x68\x75\x82\x8f\x9c\xa9\xb6\xc3"
-                       "\xd0\xdd\xea\xf7\x04\x11\x1e\x2b"
-                       "\x38\x45\x52\x5f\x6c\x79\x86\x93"
-                       "\xa0\xad\xba\xc7\xd4\xe1\xee\xfb"
-                       "\x08\x15\x22\x2f\x3c\x49\x56\x63"
-                       "\x70\x7d\x8a\x97\xa4\xb1\xbe\xcb"
-                       "\xd8\xe5\xf2\xff\x0c\x19\x26\x33"
-                       "\x40\x4d\x5a\x67\x74\x81\x8e\x9b"
-                       "\xa8\xb5\xc2\xcf\xdc\xe9\xf6\x03"
-                       "\x10\x1d\x2a\x37\x44\x51\x5e\x6b"
-                       "\x78\x85\x92\x9f\xac\xb9\xc6\xd3"
-                       "\xe0\xed\xfa\x07\x14\x21\x2e\x3b"
-                       "\x48\x55\x62\x6f\x7c\x89\x96\xa3"
-                       "\xb0\xbd\xca\xd7\xe4\xf1\xfe\x0b"
-                       "\x18\x25\x32\x3f\x4c\x59\x66\x73"
-                       "\x80\x8d\x9a\xa7\xb4\xc1\xce\xdb"
-                       "\xe8\xf5\x02\x0f\x1c\x29\x36\x43"
-                       "\x50\x5d\x6a\x77\x84\x91\x9e\xab"
-                       "\xb8\xc5\xd2\xdf\xec\xf9\x06\x13"
-                       "\x20\x2d\x3a\x47\x54\x61\x6e\x7b"
-                       "\x88\x95\xa2\xaf\xbc\xc9\xd6\xe3"
-                       "\xf0\xfd\x0a\x17\x24\x31\x3e\x4b"
-                       "\x58\x65\x72\x7f\x8c\x99\xa6\xb3"
-                       "\xc0\xcd\xda\xe7\xf4\x01\x0e\x1b"
-                       "\x28\x35\x42\x4f\x5c\x69\x76\x83"
-                       "\x90\x9d\xaa\xb7\xc4\xd1\xde\xeb"
-                       "\xf8\x05\x12\x1f\x2c\x39\x46\x53"
-                       "\x60\x6d\x7a\x87\x94\xa1\xae\xbb"
-                       "\xc8\xd5\xe2\xef\xfc\x09\x16\x23"
-                       "\x30\x3d\x4a\x57\x64\x71\x7e\x8b"
-                       "\x98\xa5\xb2\xbf\xcc\xd9\xe6\xf3"
-                       "\x00\x0f\x1e\x2d\x3c\x4b\x5a\x69"
-                       "\x78\x87\x96\xa5\xb4\xc3\xd2\xe1"
-                       "\xf0\xff\x0e\x1d\x2c\x3b\x4a\x59"
-                       "\x68\x77\x86\x95\xa4\xb3\xc2\xd1"
-                       "\xe0\xef\xfe\x0d\x1c\x2b\x3a\x49"
-                       "\x58\x67\x76\x85\x94\xa3\xb2\xc1"
-                       "\xd0\xdf\xee\xfd\x0c\x1b\x2a\x39"
-                       "\x48\x57\x66\x75\x84\x93\xa2\xb1"
-                       "\xc0\xcf\xde\xed\xfc\x0b\x1a\x29"
-                       "\x38\x47\x56\x65\x74\x83\x92\xa1"
-                       "\xb0\xbf\xce\xdd\xec\xfb\x0a\x19"
-                       "\x28\x37\x46\x55\x64\x73\x82\x91"
-                       "\xa0\xaf\xbe\xcd\xdc\xeb\xfa\x09"
-                       "\x18\x27\x36\x45\x54\x63\x72\x81"
-                       "\x90\x9f\xae\xbd\xcc\xdb\xea\xf9"
-                       "\x08\x17\x26\x35\x44\x53\x62\x71"
-                       "\x80\x8f\x9e\xad\xbc\xcb\xda\xe9"
-                       "\xf8\x07\x16\x25\x34\x43\x52\x61"
-                       "\x70\x7f\x8e\x9d\xac\xbb\xca\xd9"
-                       "\xe8\xf7\x06\x15\x24\x33\x42\x51"
-                       "\x60\x6f\x7e\x8d\x9c\xab\xba\xc9"
-                       "\xd8\xe7\xf6\x05\x14\x23\x32\x41"
-                       "\x50\x5f\x6e\x7d\x8c\x9b\xaa\xb9"
-                       "\xc8\xd7\xe6\xf5\x04\x13\x22\x31"
-                       "\x40\x4f\x5e\x6d\x7c\x8b\x9a\xa9"
-                       "\xb8\xc7\xd6\xe5\xf4\x03\x12\x21"
-                       "\x30\x3f\x4e\x5d\x6c\x7b\x8a\x99"
-                       "\xa8\xb7\xc6\xd5\xe4\xf3\x02\x11"
-                       "\x20\x2f\x3e\x4d\x5c\x6b\x7a\x89"
-                       "\x98\xa7\xb6\xc5\xd4\xe3\xf2\x01"
-                       "\x10\x1f\x2e\x3d\x4c\x5b\x6a\x79"
-                       "\x88\x97\xa6\xb5\xc4\xd3\xe2\xf1"
-                       "\x00\x11\x22\x33\x44\x55\x66\x77"
-                       "\x88\x99\xaa\xbb\xcc\xdd\xee\xff"
-                       "\x10\x21\x32\x43\x54\x65\x76\x87"
-                       "\x98\xa9\xba\xcb\xdc\xed\xfe\x0f"
-                       "\x20\x31\x42\x53\x64\x75\x86\x97"
-                       "\xa8\xb9\xca\xdb\xec\xfd\x0e\x1f"
-                       "\x30\x41\x52\x63\x74\x85\x96\xa7"
-                       "\xb8\xc9\xda\xeb\xfc\x0d\x1e\x2f"
-                       "\x40\x51\x62\x73\x84\x95\xa6\xb7"
-                       "\xc8\xd9\xea\xfb\x0c\x1d\x2e\x3f"
-                       "\x50\x61\x72\x83\x94\xa5\xb6\xc7"
-                       "\xd8\xe9\xfa\x0b\x1c\x2d\x3e\x4f"
-                       "\x60\x71\x82\x93\xa4\xb5\xc6\xd7"
-                       "\xe8\xf9\x0a\x1b\x2c\x3d\x4e\x5f"
-                       "\x70\x81\x92\xa3\xb4\xc5\xd6\xe7"
-                       "\xf8\x09\x1a\x2b\x3c\x4d\x5e\x6f"
-                       "\x80\x91\xa2\xb3\xc4\xd5\xe6\xf7"
-                       "\x08\x19\x2a\x3b\x4c\x5d\x6e\x7f"
-                       "\x90\xa1\xb2\xc3\xd4\xe5\xf6\x07"
-                       "\x18\x29\x3a\x4b\x5c\x6d\x7e\x8f"
-                       "\xa0\xb1\xc2\xd3\xe4\xf5\x06\x17"
-                       "\x28\x39\x4a\x5b\x6c\x7d\x8e\x9f"
-                       "\xb0\xc1\xd2\xe3\xf4\x05\x16\x27"
-                       "\x38\x49\x5a\x6b\x7c\x8d\x9e\xaf"
-                       "\xc0\xd1\xe2\xf3\x04\x15\x26\x37"
-                       "\x48\x59\x6a\x7b\x8c\x9d\xae\xbf"
-                       "\xd0\xe1\xf2\x03\x14\x25\x36\x47"
-                       "\x58\x69\x7a\x8b\x9c\xad\xbe\xcf"
-                       "\xe0\xf1\x02\x13\x24\x35\x46\x57"
-                       "\x68\x79\x8a\x9b\xac\xbd\xce\xdf"
-                       "\xf0\x01\x12\x23\x34\x45\x56\x67"
-                       "\x78\x89\x9a\xab\xbc\xcd\xde\xef"
-                       "\x00\x13\x26\x39\x4c\x5f\x72\x85"
-                       "\x98\xab\xbe\xd1\xe4\xf7\x0a\x1d"
-                       "\x30\x43\x56\x69\x7c\x8f\xa2\xb5"
-                       "\xc8\xdb\xee\x01\x14\x27\x3a\x4d"
-                       "\x60\x73\x86\x99\xac\xbf\xd2\xe5"
-                       "\xf8\x0b\x1e\x31\x44\x57\x6a\x7d"
-                       "\x90\xa3\xb6\xc9\xdc\xef\x02\x15"
-                       "\x28\x3b\x4e\x61\x74\x87\x9a\xad"
-                       "\xc0\xd3\xe6\xf9\x0c\x1f\x32\x45"
-                       "\x58\x6b\x7e\x91\xa4\xb7\xca\xdd"
-                       "\xf0\x03\x16\x29\x3c\x4f\x62\x75"
-                       "\x88\x9b\xae\xc1\xd4\xe7\xfa\x0d"
-                       "\x20\x33\x46\x59\x6c\x7f\x92\xa5"
-                       "\xb8\xcb\xde\xf1\x04\x17\x2a\x3d"
-                       "\x50\x63\x76\x89\x9c\xaf\xc2\xd5"
-                       "\xe8\xfb\x0e\x21\x34\x47\x5a\x6d"
-                       "\x80\x93\xa6\xb9\xcc\xdf\xf2\x05"
-                       "\x18\x2b\x3e\x51\x64\x77\x8a\x9d"
-                       "\xb0\xc3\xd6\xe9\xfc\x0f\x22\x35"
-                       "\x48\x5b\x6e\x81\x94\xa7\xba\xcd"
-                       "\xe0\xf3\x06\x19\x2c\x3f\x52\x65"
-                       "\x78\x8b\x9e\xb1\xc4\xd7\xea\xfd"
-                       "\x10\x23\x36\x49\x5c\x6f\x82\x95"
-                       "\xa8\xbb\xce\xe1\xf4\x07\x1a\x2d"
-                       "\x40\x53\x66\x79\x8c\x9f\xb2\xc5"
-                       "\xd8\xeb\xfe\x11\x24\x37\x4a\x5d"
-                       "\x70\x83\x96\xa9\xbc\xcf\xe2\xf5"
-                       "\x08\x1b\x2e\x41\x54\x67\x7a\x8d"
-                       "\xa0\xb3\xc6\xd9\xec\xff\x12\x25"
-                       "\x38\x4b\x5e\x71\x84\x97\xaa\xbd"
-                       "\xd0\xe3\xf6\x09\x1c\x2f\x42\x55"
-                       "\x68\x7b\x8e\xa1\xb4\xc7\xda\xed"
-                       "\x00\x15\x2a\x3f\x54\x69\x7e\x93"
-                       "\xa8\xbd\xd2\xe7\xfc\x11\x26\x3b"
-                       "\x50\x65\x7a\x8f\xa4\xb9\xce\xe3"
-                       "\xf8\x0d\x22\x37\x4c\x61\x76\x8b"
-                       "\xa0\xb5\xca\xdf\xf4\x09\x1e\x33"
-                       "\x48\x5d\x72\x87\x9c\xb1\xc6\xdb"
-                       "\xf0\x05\x1a\x2f\x44\x59\x6e\x83"
-                       "\x98\xad\xc2\xd7\xec\x01\x16\x2b"
-                       "\x40\x55\x6a\x7f\x94\xa9\xbe\xd3"
-                       "\xe8\xfd\x12\x27\x3c\x51\x66\x7b"
-                       "\x90\xa5\xba\xcf\xe4\xf9\x0e\x23"
-                       "\x38\x4d\x62\x77\x8c\xa1\xb6\xcb"
-                       "\xe0\xf5\x0a\x1f\x34\x49\x5e\x73"
-                       "\x88\x9d\xb2\xc7\xdc\xf1\x06\x1b"
-                       "\x30\x45\x5a\x6f\x84\x99\xae\xc3"
-                       "\xd8\xed\x02\x17\x2c\x41\x56\x6b"
-                       "\x80\x95\xaa\xbf\xd4\xe9\xfe\x13"
-                       "\x28\x3d\x52\x67\x7c\x91\xa6\xbb"
-                       "\xd0\xe5\xfa\x0f\x24\x39\x4e\x63"
-                       "\x78\x8d\xa2\xb7\xcc\xe1\xf6\x0b"
-                       "\x20\x35\x4a\x5f\x74\x89\x9e\xb3"
-                       "\xc8\xdd\xf2\x07\x1c\x31\x46\x5b"
-                       "\x70\x85\x9a\xaf\xc4\xd9\xee\x03"
-                       "\x18\x2d\x42\x57\x6c\x81\x96\xab"
-                       "\xc0\xd5\xea\xff\x14\x29\x3e\x53"
-                       "\x68\x7d\x92\xa7\xbc\xd1\xe6\xfb"
-                       "\x10\x25\x3a\x4f\x64\x79\x8e\xa3"
-                       "\xb8\xcd\xe2\xf7\x0c\x21\x36\x4b"
-                       "\x60\x75\x8a\x9f\xb4\xc9\xde\xf3"
-                       "\x08\x1d\x32\x47\x5c\x71\x86\x9b"
-                       "\xb0\xc5\xda\xef\x04\x19\x2e\x43"
-                       "\x58\x6d\x82\x97\xac\xc1\xd6\xeb"
-                       "\x00\x17\x2e\x45\x5c\x73\x8a\xa1"
-                       "\xb8\xcf\xe6\xfd\x14\x2b\x42\x59"
-                       "\x70\x87\x9e\xb5\xcc\xe3\xfa\x11"
-                       "\x28\x3f\x56\x6d\x84\x9b\xb2\xc9"
-                       "\xe0\xf7\x0e\x25\x3c\x53\x6a\x81"
-                       "\x98\xaf\xc6\xdd\xf4\x0b\x22\x39"
-                       "\x50\x67\x7e\x95\xac\xc3\xda\xf1"
-                       "\x08\x1f\x36\x4d\x64\x7b\x92\xa9"
-                       "\xc0\xd7\xee\x05\x1c\x33\x4a\x61"
-                       "\x78\x8f\xa6\xbd\xd4\xeb\x02\x19"
-                       "\x30\x47\x5e\x75\x8c\xa3\xba\xd1"
-                       "\xe8\xff\x16\x2d\x44\x5b\x72\x89"
-                       "\xa0\xb7\xce\xe5\xfc\x13\x2a\x41"
-                       "\x58\x6f\x86\x9d\xb4\xcb\xe2\xf9"
-                       "\x10\x27\x3e\x55\x6c\x83\x9a\xb1"
-                       "\xc8\xdf\xf6\x0d\x24\x3b\x52\x69"
-                       "\x80\x97\xae\xc5\xdc\xf3\x0a\x21"
-                       "\x38\x4f\x66\x7d\x94\xab\xc2\xd9"
-                       "\xf0\x07\x1e\x35\x4c\x63\x7a\x91"
-                       "\xa8\xbf\xd6\xed\x04\x1b\x32\x49"
-                       "\x60\x77\x8e\xa5\xbc\xd3\xea\x01"
-                       "\x18\x2f\x46\x5d\x74\x8b\xa2\xb9"
-                       "\xd0\xe7\xfe\x15\x2c\x43\x5a\x71"
-                       "\x88\x9f\xb6\xcd\xe4\xfb\x12\x29"
-                       "\x40\x57\x6e\x85\x9c\xb3\xca\xe1"
-                       "\xf8\x0f\x26\x3d\x54\x6b\x82\x99"
-                       "\xb0\xc7\xde\xf5\x0c\x23\x3a\x51"
-                       "\x68\x7f\x96\xad\xc4\xdb\xf2\x09"
-                       "\x20\x37\x4e\x65\x7c\x93\xaa\xc1"
-                       "\xd8\xef\x06\x1d\x34\x4b\x62\x79"
-                       "\x90\xa7\xbe\xd5\xec\x03\x1a\x31"
-                       "\x48\x5f\x76\x8d\xa4\xbb\xd2\xe9"
-                       "\x00\x19\x32\x4b\x64\x7d\x96\xaf"
-                       "\xc8\xe1\xfa\x13\x2c\x45\x5e\x77"
-                       "\x90\xa9\xc2\xdb\xf4\x0d\x26\x3f"
-                       "\x58\x71\x8a\xa3\xbc\xd5\xee\x07"
-                       "\x20\x39\x52\x6b\x84\x9d\xb6\xcf"
-                       "\xe8\x01\x1a\x33\x4c\x65\x7e\x97"
-                       "\xb0\xc9\xe2\xfb\x14\x2d\x46\x5f"
-                       "\x78\x91\xaa\xc3\xdc\xf5\x0e\x27"
-                       "\x40\x59\x72\x8b\xa4\xbd\xd6\xef"
-                       "\x08\x21\x3a\x53\x6c\x85\x9e\xb7"
-                       "\xd0\xe9\x02\x1b\x34\x4d\x66\x7f"
-                       "\x98\xb1\xca\xe3\xfc\x15\x2e\x47"
-                       "\x60\x79\x92\xab\xc4\xdd\xf6\x0f"
-                       "\x28\x41\x5a\x73\x8c\xa5\xbe\xd7"
-                       "\xf0\x09\x22\x3b\x54\x6d\x86\x9f"
-                       "\xb8\xd1\xea\x03\x1c\x35\x4e\x67"
-                       "\x80\x99\xb2\xcb\xe4\xfd\x16\x2f"
-                       "\x48\x61\x7a\x93\xac\xc5\xde\xf7"
-                       "\x10\x29\x42\x5b\x74\x8d\xa6\xbf"
-                       "\xd8\xf1\x0a\x23\x3c\x55\x6e\x87"
-                       "\xa0\xb9\xd2\xeb\x04\x1d\x36\x4f"
-                       "\x68\x81\x9a\xb3\xcc\xe5\xfe\x17"
-                       "\x30\x49\x62\x7b\x94\xad\xc6\xdf"
-                       "\xf8\x11\x2a\x43\x5c\x75\x8e\xa7"
-                       "\xc0\xd9\xf2\x0b\x24\x3d\x56\x6f"
-                       "\x88\xa1\xba\xd3\xec\x05\x1e\x37"
-                       "\x50\x69\x82\x9b\xb4\xcd\xe6\xff"
-                       "\x18\x31\x4a\x63\x7c\x95\xae\xc7"
-                       "\xe0\xf9\x12\x2b\x44\x5d\x76\x8f"
-                       "\xa8\xc1\xda\xf3\x0c\x25\x3e\x57"
-                       "\x70\x89\xa2\xbb\xd4\xed\x06\x1f"
-                       "\x38\x51\x6a\x83\x9c\xb5\xce\xe7"
-                       "\x00\x1b\x36\x51\x6c\x87\xa2\xbd"
-                       "\xd8\xf3\x0e\x29\x44\x5f\x7a\x95"
-                       "\xb0\xcb\xe6\x01\x1c\x37\x52\x6d"
-                       "\x88\xa3\xbe\xd9\xf4\x0f\x2a\x45"
-                       "\x60\x7b\x96\xb1\xcc\xe7\x02\x1d"
-                       "\x38\x53\x6e\x89\xa4\xbf\xda\xf5"
-                       "\x10\x2b\x46\x61\x7c\x97\xb2\xcd"
-                       "\xe8\x03\x1e\x39\x54\x6f\x8a\xa5"
-                       "\xc0\xdb\xf6\x11\x2c\x47\x62\x7d"
-                       "\x98\xb3\xce\xe9\x04\x1f\x3a\x55"
-                       "\x70\x8b\xa6\xc1\xdc\xf7\x12\x2d"
-                       "\x48\x63\x7e\x99\xb4\xcf\xea\x05"
-                       "\x20\x3b\x56\x71\x8c\xa7\xc2\xdd"
-                       "\xf8\x13\x2e\x49\x64\x7f\x9a\xb5"
-                       "\xd0\xeb\x06\x21\x3c\x57\x72\x8d"
-                       "\xa8\xc3\xde\xf9\x14\x2f\x4a\x65"
-                       "\x80\x9b\xb6\xd1\xec\x07\x22\x3d"
-                       "\x58\x73\x8e\xa9\xc4\xdf\xfa\x15"
-                       "\x30\x4b\x66\x81\x9c\xb7\xd2\xed"
-                       "\x08\x23\x3e\x59\x74\x8f\xaa\xc5"
-                       "\xe0\xfb\x16\x31\x4c\x67\x82\x9d"
-                       "\xb8\xd3\xee\x09\x24\x3f\x5a\x75"
-                       "\x90\xab\xc6\xe1\xfc\x17\x32\x4d"
-                       "\x68\x83\x9e\xb9\xd4\xef\x0a\x25"
-                       "\x40\x5b\x76\x91\xac\xc7\xe2\xfd"
-                       "\x18\x33\x4e\x69\x84\x9f\xba\xd5"
-                       "\xf0\x0b\x26\x41\x5c\x77\x92\xad"
-                       "\xc8\xe3\xfe\x19\x34\x4f\x6a\x85"
-                       "\xa0\xbb\xd6\xf1\x0c\x27\x42\x5d"
-                       "\x78\x93\xae\xc9\xe4\xff\x1a\x35"
-                       "\x50\x6b\x86\xa1\xbc\xd7\xf2\x0d"
-                       "\x28\x43\x5e\x79\x94\xaf\xca\xe5"
-                       "\x00\x1d\x3a\x57\x74\x91\xae\xcb"
-                       "\xe8\x05\x22\x3f\x5c\x79\x96\xb3"
-                       "\xd0\xed\x0a\x27\x44\x61\x7e\x9b"
-                       "\xb8\xd5\xf2\x0f\x2c\x49\x66\x83"
-                       "\xa0\xbd\xda\xf7\x14\x31\x4e\x6b"
-                       "\x88\xa5\xc2\xdf\xfc\x19\x36\x53"
-                       "\x70\x8d\xaa\xc7\xe4\x01\x1e\x3b"
-                       "\x58\x75\x92\xaf\xcc\xe9\x06\x23"
-                       "\x40\x5d\x7a\x97\xb4\xd1\xee\x0b"
-                       "\x28\x45\x62\x7f\x9c\xb9\xd6\xf3"
-                       "\x10\x2d\x4a\x67\x84\xa1\xbe\xdb"
-                       "\xf8\x15\x32\x4f\x6c\x89\xa6\xc3"
-                       "\xe0\xfd\x1a\x37\x54\x71\x8e\xab"
-                       "\xc8\xe5\x02\x1f\x3c\x59\x76\x93"
-                       "\xb0\xcd\xea\x07\x24\x41\x5e\x7b"
-                       "\x98\xb5\xd2\xef\x0c\x29\x46\x63"
-                       "\x80\x9d\xba\xd7\xf4\x11\x2e\x4b"
-                       "\x68\x85\xa2\xbf\xdc\xf9\x16\x33"
-                       "\x50\x6d\x8a\xa7\xc4\xe1\xfe\x1b"
-                       "\x38\x55\x72\x8f\xac\xc9\xe6\x03"
-                       "\x20\x3d\x5a\x77\x94\xb1\xce\xeb"
-                       "\x08\x25\x42\x5f\x7c\x99\xb6\xd3"
-                       "\xf0\x0d\x2a\x47\x64\x81\x9e\xbb"
-                       "\xd8\xf5\x12\x2f\x4c\x69\x86\xa3"
-                       "\xc0\xdd\xfa\x17\x34\x51\x6e\x8b"
-                       "\xa8\xc5\xe2\xff\x1c\x39\x56\x73"
-                       "\x90\xad\xca\xe7\x04\x21\x3e\x5b"
-                       "\x78\x95\xb2\xcf\xec\x09\x26\x43"
-                       "\x60\x7d\x9a\xb7\xd4\xf1\x0e\x2b"
-                       "\x48\x65\x82\x9f\xbc\xd9\xf6\x13"
-                       "\x30\x4d\x6a\x87\xa4\xc1\xde\xfb"
-                       "\x18\x35\x52\x6f\x8c\xa9\xc6\xe3"
-                       "\x00\x1f\x3e\x5d\x7c\x9b\xba\xd9"
-                       "\xf8\x17\x36\x55\x74\x93\xb2\xd1"
-                       "\xf0\x0f\x2e\x4d\x6c\x8b\xaa\xc9"
-                       "\xe8\x07\x26\x45\x64\x83\xa2\xc1"
-                       "\xe0\xff\x1e\x3d\x5c\x7b\x9a\xb9"
-                       "\xd8\xf7\x16\x35\x54\x73\x92\xb1"
-                       "\xd0\xef\x0e\x2d\x4c\x6b\x8a\xa9"
-                       "\xc8\xe7\x06\x25\x44\x63\x82\xa1"
-                       "\xc0\xdf\xfe\x1d\x3c\x5b\x7a\x99"
-                       "\xb8\xd7\xf6\x15\x34\x53\x72\x91"
-                       "\xb0\xcf\xee\x0d\x2c\x4b\x6a\x89"
-                       "\xa8\xc7\xe6\x05\x24\x43\x62\x81"
-                       "\xa0\xbf\xde\xfd\x1c\x3b\x5a\x79"
-                       "\x98\xb7\xd6\xf5\x14\x33\x52\x71"
-                       "\x90\xaf\xce\xed\x0c\x2b\x4a\x69"
-                       "\x88\xa7\xc6\xe5\x04\x23\x42\x61"
-                       "\x80\x9f\xbe\xdd\xfc\x1b\x3a\x59"
-                       "\x78\x97\xb6\xd5\xf4\x13\x32\x51"
-                       "\x70\x8f\xae\xcd\xec\x0b\x2a\x49"
-                       "\x68\x87\xa6\xc5\xe4\x03\x22\x41"
-                       "\x60\x7f\x9e\xbd\xdc\xfb\x1a\x39"
-                       "\x58\x77\x96\xb5\xd4\xf3\x12\x31"
-                       "\x50\x6f\x8e\xad\xcc\xeb\x0a\x29"
-                       "\x48\x67\x86\xa5\xc4\xe3\x02\x21"
-                       "\x40\x5f\x7e\x9d\xbc\xdb\xfa\x19"
-                       "\x38\x57\x76\x95\xb4\xd3\xf2\x11"
-                       "\x30\x4f\x6e\x8d\xac\xcb\xea\x09"
-                       "\x28\x47\x66\x85\xa4\xc3\xe2\x01"
-                       "\x20\x3f\x5e\x7d\x9c\xbb\xda\xf9"
-                       "\x18\x37\x56\x75\x94\xb3\xd2\xf1"
-                       "\x10\x2f\x4e\x6d\x8c\xab\xca\xe9"
-                       "\x08\x27\x46\x65\x84\xa3\xc2\xe1"
-                       "\x00\x21\x42\x63",
-               .ilen = 4100,
-               .result =
-                       "\xf0\x5c\x74\xad\x4e\xbc\x99\xe2"
-                       "\xae\xff\x91\x3a\x44\xcf\x38\x32"
-                       "\x1e\xad\xa7\xcd\xa1\x39\x95\xaa"
-                       "\x10\xb1\xb3\x2e\x04\x31\x8f\x86"
-                       "\xf2\x62\x74\x70\x0c\xa4\x46\x08"
-                       "\xa8\xb7\x99\xa8\xe9\xd2\x73\x79"
-                       "\x7e\x6e\xd4\x8f\x1e\xc7\x8e\x31"
-                       "\x0b\xfa\x4b\xce\xfd\xf3\x57\x71"
-                       "\xe9\x46\x03\xa5\x3d\x34\x00\xe2"
-                       "\x18\xff\x75\x6d\x06\x2d\x00\xab"
-                       "\xb9\x3e\x6c\x59\xc5\x84\x06\xb5"
-                       "\x8b\xd0\x89\x9c\x4a\x79\x16\xc6"
-                       "\x3d\x74\x54\xfa\x44\xcd\x23\x26"
-                       "\x5c\xcf\x7e\x28\x92\x32\xbf\xdf"
-                       "\xa7\x20\x3c\x74\x58\x2a\x9a\xde"
-                       "\x61\x00\x1c\x4f\xff\x59\xc4\x22"
-                       "\xac\x3c\xd0\xe8\x6c\xf9\x97\x1b"
-                       "\x58\x9b\xad\x71\xe8\xa9\xb5\x0d"
-                       "\xee\x2f\x04\x1f\x7f\xbc\x99\xee"
-                       "\x84\xff\x42\x60\xdc\x3a\x18\xa5"
-                       "\x81\xf9\xef\xdc\x7a\x0f\x65\x41"
-                       "\x2f\xa3\xd3\xf9\xc2\xcb\xc0\x4d"
-                       "\x8f\xd3\x76\x96\xad\x49\x6d\x38"
-                       "\x3d\x39\x0b\x6c\x80\xb7\x54\x69"
-                       "\xf0\x2c\x90\x02\x29\x0d\x1c\x12"
-                       "\xad\x55\xc3\x8b\x68\xd9\xcc\xb3"
-                       "\xb2\x64\x33\x90\x5e\xca\x4b\xe2"
-                       "\xfb\x75\xdc\x63\xf7\x9f\x82\x74"
-                       "\xf0\xc9\xaa\x7f\xe9\x2a\x9b\x33"
-                       "\xbc\x88\x00\x7f\xca\xb2\x1f\x14"
-                       "\xdb\xc5\x8e\x7b\x11\x3c\x3e\x08"
-                       "\xf3\x83\xe8\xe0\x94\x86\x2e\x92"
-                       "\x78\x6b\x01\xc9\xc7\x83\xba\x21"
-                       "\x6a\x25\x15\x33\x4e\x45\x08\xec"
-                       "\x35\xdb\xe0\x6e\x31\x51\x79\xa9"
-                       "\x42\x44\x65\xc1\xa0\xf1\xf9\x2a"
-                       "\x70\xd5\xb6\xc6\xc1\x8c\x39\xfc"
-                       "\x25\xa6\x55\xd9\xdd\x2d\x4c\xec"
-                       "\x49\xc6\xeb\x0e\xa8\x25\x2a\x16"
-                       "\x1b\x66\x84\xda\xe2\x92\xe5\xc0"
-                       "\xc8\x53\x07\xaf\x80\x84\xec\xfd"
-                       "\xcd\xd1\x6e\xcd\x6f\x6a\xf5\x36"
-                       "\xc5\x15\xe5\x25\x7d\x77\xd1\x1a"
-                       "\x93\x36\xa9\xcf\x7c\xa4\x54\x4a"
-                       "\x06\x51\x48\x4e\xf6\x59\x87\xd2"
-                       "\x04\x02\xef\xd3\x44\xde\x76\x31"
-                       "\xb3\x34\x17\x1b\x9d\x66\x11\x9f"
-                       "\x1e\xcc\x17\xe9\xc7\x3c\x1b\xe7"
-                       "\xcb\x50\x08\xfc\xdc\x2b\x24\xdb"
-                       "\x65\x83\xd0\x3b\xe3\x30\xea\x94"
-                       "\x6c\xe7\xe8\x35\x32\xc7\xdb\x64"
-                       "\xb4\x01\xab\x36\x2c\x77\x13\xaf"
-                       "\xf8\x2b\x88\x3f\x54\x39\xc4\x44"
-                       "\xfe\xef\x6f\x68\x34\xbe\x0f\x05"
-                       "\x16\x6d\xf6\x0a\x30\xe7\xe3\xed"
-                       "\xc4\xde\x3c\x1b\x13\xd8\xdb\xfe"
-                       "\x41\x62\xe5\x28\xd4\x8d\xa3\xc7"
-                       "\x93\x97\xc6\x48\x45\x1d\x9f\x83"
-                       "\xdf\x4b\x40\x3e\x42\x25\x87\x80"
-                       "\x4c\x7d\xa8\xd4\x98\x23\x95\x75"
-                       "\x41\x8c\xda\x41\x9b\xd4\xa7\x06"
-                       "\xb5\xf1\x71\x09\x53\xbe\xca\xbf"
-                       "\x32\x03\xed\xf0\x50\x1c\x56\x39"
-                       "\x5b\xa4\x75\x18\xf7\x9b\x58\xef"
-                       "\x53\xfc\x2a\x38\x23\x15\x75\xcd"
-                       "\x45\xe5\x5a\x82\x55\xba\x21\xfa"
-                       "\xd4\xbd\xc6\x94\x7c\xc5\x80\x12"
-                       "\xf7\x4b\x32\xc4\x9a\x82\xd8\x28"
-                       "\x8f\xd9\xc2\x0f\x60\x03\xbe\x5e"
-                       "\x21\xd6\x5f\x58\xbf\x5c\xb1\x32"
-                       "\x82\x8d\xa9\xe5\xf2\x66\x1a\xc0"
-                       "\xa0\xbc\x58\x2f\x71\xf5\x2f\xed"
-                       "\xd1\x26\xb9\xd8\x49\x5a\x07\x19"
-                       "\x01\x7c\x59\xb0\xf8\xa4\xb7\xd3"
-                       "\x7b\x1a\x8c\x38\xf4\x50\xa4\x59"
-                       "\xb0\xcc\x41\x0b\x88\x7f\xe5\x31"
-                       "\xb3\x42\xba\xa2\x7e\xd4\x32\x71"
-                       "\x45\x87\x48\xa9\xc2\xf2\x89\xb3"
-                       "\xe4\xa7\x7e\x52\x15\x61\xfa\xfe"
-                       "\xc9\xdd\x81\xeb\x13\xab\xab\xc3"
-                       "\x98\x59\xd8\x16\x3d\x14\x7a\x1c"
-                       "\x3c\x41\x9a\x16\x16\x9b\xd2\xd2"
-                       "\x69\x3a\x29\x23\xac\x86\x32\xa5"
-                       "\x48\x9c\x9e\xf3\x47\x77\x81\x70"
-                       "\x24\xe8\x85\xd2\xf5\xb5\xfa\xff"
-                       "\x59\x6a\xd3\x50\x59\x43\x59\xde"
-                       "\xd9\xf1\x55\xa5\x0c\xc3\x1a\x1a"
-                       "\x18\x34\x0d\x1a\x63\x33\xed\x10"
-                       "\xe0\x1d\x2a\x18\xd2\xc0\x54\xa8"
-                       "\xca\xb5\x9a\xd3\xdd\xca\x45\x84"
-                       "\x50\xe7\x0f\xfe\xa4\x99\x5a\xbe"
-                       "\x43\x2d\x9a\xcb\x92\x3f\x5a\x1d"
-                       "\x85\xd8\xc9\xdf\x68\xc9\x12\x80"
-                       "\x56\x0c\xdc\x00\xdc\x3a\x7d\x9d"
-                       "\xa3\xa2\xe8\x4d\xbf\xf9\x70\xa0"
-                       "\xa4\x13\x4f\x6b\xaf\x0a\x89\x7f"
-                       "\xda\xf0\xbf\x9b\xc8\x1d\xe5\xf8"
-                       "\x2e\x8b\x07\xb5\x73\x1b\xcc\xa2"
-                       "\xa6\xad\x30\xbc\x78\x3c\x5b\x10"
-                       "\xfa\x5e\x62\x2d\x9e\x64\xb3\x33"
-                       "\xce\xf9\x1f\x86\xe7\x8b\xa2\xb8"
-                       "\xe8\x99\x57\x8c\x11\xed\x66\xd9"
-                       "\x3c\x72\xb9\xc3\xe6\x4e\x17\x3a"
-                       "\x6a\xcb\x42\x24\x06\xed\x3e\x4e"
-                       "\xa3\xe8\x6a\x94\xda\x0d\x4e\xd5"
-                       "\x14\x19\xcf\xb6\x26\xd8\x2e\xcc"
-                       "\x64\x76\x38\x49\x4d\xfe\x30\x6d"
-                       "\xe4\xc8\x8c\x7b\xc4\xe0\x35\xba"
-                       "\x22\x6e\x76\xe1\x1a\xf2\x53\xc3"
-                       "\x28\xa2\x82\x1f\x61\x69\xad\xc1"
-                       "\x7b\x28\x4b\x1e\x6c\x85\x95\x9b"
-                       "\x51\xb5\x17\x7f\x12\x69\x8c\x24"
-                       "\xd5\xc7\x5a\x5a\x11\x54\xff\x5a"
-                       "\xf7\x16\xc3\x91\xa6\xf0\xdc\x0a"
-                       "\xb6\xa7\x4a\x0d\x7a\x58\xfe\xa5"
-                       "\xf5\xcb\x8f\x7b\x0e\xea\x57\xe7"
-                       "\xbd\x79\xd6\x1c\x88\x23\x6c\xf2"
-                       "\x4d\x29\x77\x53\x35\x6a\x00\x8d"
-                       "\xcd\xa3\x58\xbe\x77\x99\x18\xf8"
-                       "\xe6\xe1\x8f\xe9\x37\x8f\xe3\xe2"
-                       "\x5a\x8a\x93\x25\xaf\xf3\x78\x80"
-                       "\xbe\xa6\x1b\xc6\xac\x8b\x1c\x91"
-                       "\x58\xe1\x9f\x89\x35\x9d\x1d\x21"
-                       "\x29\x9f\xf4\x99\x02\x27\x0f\xa8"
-                       "\x4f\x79\x94\x2b\x33\x2c\xda\xa2"
-                       "\x26\x39\x83\x94\xef\x27\xd8\x53"
-                       "\x8f\x66\x0d\xe4\x41\x7d\x34\xcd"
-                       "\x43\x7c\x95\x0a\x53\xef\x66\xda"
-                       "\x7e\x9b\xf3\x93\xaf\xd0\x73\x71"
-                       "\xba\x40\x9b\x74\xf8\xd7\xd7\x41"
-                       "\x6d\xaf\x72\x9c\x8d\x21\x87\x3c"
-                       "\xfd\x0a\x90\xa9\x47\x96\x9e\xd3"
-                       "\x88\xee\x73\xcf\x66\x2f\x52\x56"
-                       "\x6d\xa9\x80\x4c\xe2\x6f\x62\x88"
-                       "\x3f\x0e\x54\x17\x48\x80\x5d\xd3"
-                       "\xc3\xda\x25\x3d\xa1\xc8\xcb\x9f"
-                       "\x9b\x70\xb3\xa1\xeb\x04\x52\xa1"
-                       "\xf2\x22\x0f\xfc\xc8\x18\xfa\xf9"
-                       "\x85\x9c\xf1\xac\xeb\x0c\x02\x46"
-                       "\x75\xd2\xf5\x2c\xe3\xd2\x59\x94"
-                       "\x12\xf3\x3c\xfc\xd7\x92\xfa\x36"
-                       "\xba\x61\x34\x38\x7c\xda\x48\x3e"
-                       "\x08\xc9\x39\x23\x5e\x02\x2c\x1a"
-                       "\x18\x7e\xb4\xd9\xfd\x9e\x40\x02"
-                       "\xb1\x33\x37\x32\xe7\xde\xd6\xd0"
-                       "\x7c\x58\x65\x4b\xf8\x34\x27\x9c"
-                       "\x44\xb4\xbd\xe9\xe9\x4c\x78\x7d"
-                       "\x4b\x9f\xce\xb1\xcd\x47\xa5\x37"
-                       "\xe5\x6d\xbd\xb9\x43\x94\x0a\xd4"
-                       "\xd6\xf9\x04\x5f\xb5\x66\x6c\x1a"
-                       "\x35\x12\xe3\x36\x28\x27\x36\x58"
-                       "\x01\x2b\x79\xe4\xba\x6d\x10\x7d"
-                       "\x65\xdf\x84\x95\xf4\xd5\xb6\x8f"
-                       "\x2b\x9f\x96\x00\x86\x60\xf0\x21"
-                       "\x76\xa8\x6a\x8c\x28\x1c\xb3\x6b"
-                       "\x97\xd7\xb6\x53\x2a\xcc\xab\x40"
-                       "\x9d\x62\x79\x58\x52\xe6\x65\xb7"
-                       "\xab\x55\x67\x9c\x89\x7c\x03\xb0"
-                       "\x73\x59\xc5\x81\xf5\x18\x17\x5c"
-                       "\x89\xf3\x78\x35\x44\x62\x78\x72"
-                       "\xd0\x96\xeb\x31\xe7\x87\x77\x14"
-                       "\x99\x51\xf2\x59\x26\x9e\xb5\xa6"
-                       "\x45\xfe\x6e\xbd\x07\x4c\x94\x5a"
-                       "\xa5\x7d\xfc\xf1\x2b\x77\xe2\xfe"
-                       "\x17\xd4\x84\xa0\xac\xb5\xc7\xda"
-                       "\xa9\x1a\xb6\xf3\x74\x11\xb4\x9d"
-                       "\xfb\x79\x2e\x04\x2d\x50\x28\x83"
-                       "\xbf\xc6\x52\xd3\x34\xd6\xe8\x7a"
-                       "\xb6\xea\xe7\xa8\x6c\x15\x1e\x2c"
-                       "\x57\xbc\x48\x4e\x5f\x5c\xb6\x92"
-                       "\xd2\x49\x77\x81\x6d\x90\x70\xae"
-                       "\x98\xa1\x03\x0d\x6b\xb9\x77\x14"
-                       "\xf1\x4e\x23\xd3\xf8\x68\xbd\xc2"
-                       "\xfe\x04\xb7\x5c\xc5\x17\x60\x8f"
-                       "\x65\x54\xa4\x7a\x42\xdc\x18\x0d"
-                       "\xb5\xcf\x0f\xd3\xc7\x91\x66\x1b"
-                       "\x45\x42\x27\x75\x50\xe5\xee\xb8"
-                       "\x7f\x33\x2c\xba\x4a\x92\x4d\x2c"
-                       "\x3c\xe3\x0d\x80\x01\xba\x0d\x29"
-                       "\xd8\x3c\xe9\x13\x16\x57\xe6\xea"
-                       "\x94\x52\xe7\x00\x4d\x30\xb0\x0f"
-                       "\x35\xb8\xb8\xa7\xb1\xb5\x3b\x44"
-                       "\xe1\x2f\xfd\x88\xed\x43\xe7\x52"
-                       "\x10\x93\xb3\x8a\x30\x6b\x0a\xf7"
-                       "\x23\xc6\x50\x9d\x4a\xb0\xde\xc3"
-                       "\xdc\x9b\x2f\x01\x56\x36\x09\xc5"
-                       "\x2f\x6b\xfe\xf1\xd8\x27\x45\x03"
-                       "\x30\x5e\x5c\x5b\xb4\x62\x0e\x1a"
-                       "\xa9\x21\x2b\x92\x94\x87\x62\x57"
-                       "\x4c\x10\x74\x1a\xf1\x0a\xc5\x84"
-                       "\x3b\x9e\x72\x02\xd7\xcc\x09\x56"
-                       "\xbd\x54\xc1\xf0\xc3\xe3\xb3\xf8"
-                       "\xd2\x0d\x61\xcb\xef\xce\x0d\x05"
-                       "\xb0\x98\xd9\x8e\x4f\xf9\xbc\x93"
-                       "\xa6\xea\xc8\xcf\x10\x53\x4b\xf1"
-                       "\xec\xfc\x89\xf9\x64\xb0\x22\xbf"
-                       "\x9e\x55\x46\x9f\x7c\x50\x8e\x84"
-                       "\x54\x20\x98\xd7\x6c\x40\x1e\xdb"
-                       "\x69\x34\x78\x61\x24\x21\x9c\x8a"
-                       "\xb3\x62\x31\x8b\x6e\xf5\x2a\x35"
-                       "\x86\x13\xb1\x6c\x64\x2e\x41\xa5"
-                       "\x05\xf2\x42\xba\xd2\x3a\x0d\x8e"
-                       "\x8a\x59\x94\x3c\xcf\x36\x27\x82"
-                       "\xc2\x45\xee\x58\xcd\x88\xb4\xec"
-                       "\xde\xb2\x96\x0a\xaf\x38\x6f\x88"
-                       "\xd7\xd8\xe1\xdf\xb9\x96\xa9\x0a"
-                       "\xb1\x95\x28\x86\x20\xe9\x17\x49"
-                       "\xa2\x29\x38\xaa\xa5\xe9\x6e\xf1"
-                       "\x19\x27\xc0\xd5\x2a\x22\xc3\x0b"
-                       "\xdb\x7c\x73\x10\xb9\xba\x89\x76"
-                       "\x54\xae\x7d\x71\xb3\x93\xf6\x32"
-                       "\xe6\x47\x43\x55\xac\xa0\x0d\xc2"
-                       "\x93\x27\x4a\x8e\x0e\x74\x15\xc7"
-                       "\x0b\x85\xd9\x0c\xa9\x30\x7a\x3e"
-                       "\xea\x8f\x85\x6d\x3a\x12\x4f\x72"
-                       "\x69\x58\x7a\x80\xbb\xb5\x97\xf3"
-                       "\xcf\x70\xd2\x5d\xdd\x4d\x21\x79"
-                       "\x54\x4d\xe4\x05\xe8\xbd\xc2\x62"
-                       "\xb1\x3b\x77\x1c\xd6\x5c\xf3\xa0"
-                       "\x79\x00\xa8\x6c\x29\xd9\x18\x24"
-                       "\x36\xa2\x46\xc0\x96\x65\x7f\xbd"
-                       "\x2a\xed\x36\x16\x0c\xaa\x9f\xf4"
-                       "\xc5\xb4\xe2\x12\xed\x69\xed\x4f"
-                       "\x26\x2c\x39\x52\x89\x98\xe7\x2c"
-                       "\x99\xa4\x9e\xa3\x9b\x99\x46\x7a"
-                       "\x3a\xdc\xa8\x59\xa3\xdb\xc3\x3b"
-                       "\x95\x0d\x3b\x09\x6e\xee\x83\x5d"
-                       "\x32\x4d\xed\xab\xfa\x98\x14\x4e"
-                       "\xc3\x15\x45\x53\x61\xc4\x93\xbd"
-                       "\x90\xf4\x99\x95\x4c\xe6\x76\x92"
-                       "\x29\x90\x46\x30\x92\x69\x7d\x13"
-                       "\xf2\xa5\xcd\x69\x49\x44\xb2\x0f"
-                       "\x63\x40\x36\x5f\x09\xe2\x78\xf8"
-                       "\x91\xe3\xe2\xfa\x10\xf7\xc8\x24"
-                       "\xa8\x89\x32\x5c\x37\x25\x1d\xb2"
-                       "\xea\x17\x8a\x0a\xa9\x64\xc3\x7c"
-                       "\x3c\x7c\xbd\xc6\x79\x34\xe7\xe2"
-                       "\x85\x8e\xbf\xf8\xde\x92\xa0\xae"
-                       "\x20\xc4\xf6\xbb\x1f\x38\x19\x0e"
-                       "\xe8\x79\x9c\xa1\x23\xe9\x54\x7e"
-                       "\x37\x2f\xe2\x94\x32\xaf\xa0\x23"
-                       "\x49\xe4\xc0\xb3\xac\x00\x8f\x36"
-                       "\x05\xc4\xa6\x96\xec\x05\x98\x4f"
-                       "\x96\x67\x57\x1f\x20\x86\x1b\x2d"
-                       "\x69\xe4\x29\x93\x66\x5f\xaf\x6b"
-                       "\x88\x26\x2c\x67\x02\x4b\x52\xd0"
-                       "\x83\x7a\x43\x1f\xc0\x71\x15\x25"
-                       "\x77\x65\x08\x60\x11\x76\x4c\x8d"
-                       "\xed\xa9\x27\xc6\xb1\x2a\x2c\x6a"
-                       "\x4a\x97\xf5\xc6\xb7\x70\x42\xd3"
-                       "\x03\xd1\x24\x95\xec\x6d\xab\x38"
-                       "\x72\xce\xe2\x8b\x33\xd7\x51\x09"
-                       "\xdc\x45\xe0\x09\x96\x32\xf3\xc4"
-                       "\x84\xdc\x73\x73\x2d\x1b\x11\x98"
-                       "\xc5\x0e\x69\x28\x94\xc7\xb5\x4d"
-                       "\xc8\x8a\xd0\xaa\x13\x2e\x18\x74"
-                       "\xdd\xd1\x1e\xf3\x90\xe8\xfc\x9a"
-                       "\x72\x4a\x0e\xd1\xe4\xfb\x0d\x96"
-                       "\xd1\x0c\x79\x85\x1b\x1c\xfe\xe1"
-                       "\x62\x8f\x7a\x73\x32\xab\xc8\x18"
-                       "\x69\xe3\x34\x30\xdf\x13\xa6\xe5"
-                       "\xe8\x0e\x67\x7f\x81\x11\xb4\x60"
-                       "\xc7\xbd\x79\x65\x50\xdc\xc4\x5b"
-                       "\xde\x39\xa4\x01\x72\x63\xf3\xd1"
-                       "\x64\x4e\xdf\xfc\x27\x92\x37\x0d"
-                       "\x57\xcd\x11\x4f\x11\x04\x8e\x1d"
-                       "\x16\xf7\xcd\x92\x9a\x99\x30\x14"
-                       "\xf1\x7c\x67\x1b\x1f\x41\x0b\xe8"
-                       "\x32\xe8\xb8\xc1\x4f\x54\x86\x4f"
-                       "\xe5\x79\x81\x73\xcd\x43\x59\x68"
-                       "\x73\x02\x3b\x78\x21\x72\x43\x00"
-                       "\x49\x17\xf7\x00\xaf\x68\x24\x53"
-                       "\x05\x0a\xc3\x33\xe0\x33\x3f\x69"
-                       "\xd2\x84\x2f\x0b\xed\xde\x04\xf4"
-                       "\x11\x94\x13\x69\x51\x09\x28\xde"
-                       "\x57\x5c\xef\xdc\x9a\x49\x1c\x17"
-                       "\x97\xf3\x96\xc1\x7f\x5d\x2e\x7d"
-                       "\x55\xb8\xb3\x02\x09\xb3\x1f\xe7"
-                       "\xc9\x8d\xa3\x36\x34\x8a\x77\x13"
-                       "\x30\x63\x4c\xa5\xcd\xc3\xe0\x7e"
-                       "\x05\xa1\x7b\x0c\xcb\x74\x47\x31"
-                       "\x62\x03\x43\xf1\x87\xb4\xb0\x85"
-                       "\x87\x8e\x4b\x25\xc7\xcf\xae\x4b"
-                       "\x36\x46\x3e\x62\xbc\x6f\xeb\x5f"
-                       "\x73\xac\xe6\x07\xee\xc1\xa1\xd6"
-                       "\xc4\xab\xc9\xd6\x89\x45\xe1\xf1"
-                       "\x04\x4e\x1a\x6f\xbb\x4f\x3a\xa3"
-                       "\xa0\xcb\xa3\x0a\xd8\x71\x35\x55"
-                       "\xe4\xbc\x2e\x04\x06\xe6\xff\x5b"
-                       "\x1c\xc0\x11\x7c\xc5\x17\xf3\x38"
-                       "\xcf\xe9\xba\x0f\x0e\xef\x02\xc2"
-                       "\x8d\xc6\xbc\x4b\x67\x20\x95\xd7"
-                       "\x2c\x45\x5b\x86\x44\x8c\x6f\x2e"
-                       "\x7e\x9f\x1c\x77\xba\x6b\x0e\xa3"
-                       "\x69\xdc\xab\x24\x57\x60\x47\xc1"
-                       "\xd1\xa5\x9d\x23\xe6\xb1\x37\xfe"
-                       "\x93\xd2\x4c\x46\xf9\x0c\xc6\xfb"
-                       "\xd6\x9d\x99\x69\xab\x7a\x07\x0c"
-                       "\x65\xe7\xc4\x08\x96\xe2\xa5\x01"
-                       "\x3f\x46\x07\x05\x7e\xe8\x9a\x90"
-                       "\x50\xdc\xe9\x7a\xea\xa1\x39\x6e"
-                       "\x66\xe4\x6f\xa5\x5f\xb2\xd9\x5b"
-                       "\xf5\xdb\x2a\x32\xf0\x11\x6f\x7c"
-                       "\x26\x10\x8f\x3d\x80\xe9\x58\xf7"
-                       "\xe0\xa8\x57\xf8\xdb\x0e\xce\x99"
-                       "\x63\x19\x3d\xd5\xec\x1b\x77\x69"
-                       "\x98\xf6\xe4\x5f\x67\x17\x4b\x09"
-                       "\x85\x62\x82\x70\x18\xe2\x9a\x78"
-                       "\xe2\x62\xbd\xb4\xf1\x42\xc6\xfb"
-                       "\x08\xd0\xbd\xeb\x4e\x09\xf2\xc8"
-                       "\x1e\xdc\x3d\x32\x21\x56\x9c\x4f"
-                       "\x35\xf3\x61\x06\x72\x84\xc4\x32"
-                       "\xf2\xf1\xfa\x0b\x2f\xc3\xdb\x02"
-                       "\x04\xc2\xde\x57\x64\x60\x8d\xcf"
-                       "\xcb\x86\x5d\x97\x3e\xb1\x9c\x01"
-                       "\xd6\x28\x8f\x99\xbc\x46\xeb\x05"
-                       "\xaf\x7e\xb8\x21\x2a\x56\x85\x1c"
-                       "\xb3\x71\xa0\xde\xca\x96\xf1\x78"
-                       "\x49\xa2\x99\x81\x80\x5c\x01\xf5"
-                       "\xa0\xa2\x56\x63\xe2\x70\x07\xa5"
-                       "\x95\xd6\x85\xeb\x36\x9e\xa9\x51"
-                       "\x66\x56\x5f\x1d\x02\x19\xe2\xf6"
-                       "\x4f\x73\x38\x09\x75\x64\x48\xe0"
-                       "\xf1\x7e\x0e\xe8\x9d\xf9\xed\x94"
-                       "\xfe\x16\x26\x62\x49\x74\xf4\xb0"
-                       "\xd4\xa9\x6c\xb0\xfd\x53\xe9\x81"
-                       "\xe0\x7a\xbf\xcf\xb5\xc4\x01\x81"
-                       "\x79\x99\x77\x01\x3b\xe9\xa2\xb6"
-                       "\xe6\x6a\x8a\x9e\x56\x1c\x8d\x1e"
-                       "\x8f\x06\x55\x2c\x6c\xdc\x92\x87"
-                       "\x64\x3b\x4b\x19\xa1\x13\x64\x1d"
-                       "\x4a\xe9\xc0\x00\xb8\x95\xef\x6b"
-                       "\x1a\x86\x6d\x37\x52\x02\xc2\xe0"
-                       "\xc8\xbb\x42\x0c\x02\x21\x4a\xc9"
-                       "\xef\xa0\x54\xe4\x5e\x16\x53\x81"
-                       "\x70\x62\x10\xaf\xde\xb8\xb5\xd3"
-                       "\xe8\x5e\x6c\xc3\x8a\x3e\x18\x07"
-                       "\xf2\x2f\x7d\xa7\xe1\x3d\x4e\xb4"
-                       "\x26\xa7\xa3\x93\x86\xb2\x04\x1e"
-                       "\x53\x5d\x86\xd6\xde\x65\xca\xe3"
-                       "\x4e\xc1\xcf\xef\xc8\x70\x1b\x83"
-                       "\x13\xdd\x18\x8b\x0d\x76\xd2\xf6"
-                       "\x37\x7a\x93\x7a\x50\x11\x9f\x96"
-                       "\x86\x25\xfd\xac\xdc\xbe\x18\x93"
-                       "\x19\x6b\xec\x58\x4f\xb9\x75\xa7"
-                       "\xdd\x3f\x2f\xec\xc8\x5a\x84\xab"
-                       "\xd5\xe4\x8a\x07\xf6\x4d\x23\xd6"
-                       "\x03\xfb\x03\x6a\xea\x66\xbf\xd4"
-                       "\xb1\x34\xfb\x78\xe9\x55\xdc\x7c"
-                       "\x3d\x9c\xe5\x9a\xac\xc3\x7a\x80"
-                       "\x24\x6d\xa0\xef\x25\x7c\xb7\xea"
-                       "\xce\x4d\x5f\x18\x60\xce\x87\x22"
-                       "\x66\x2f\xd5\xdd\xdd\x02\x21\x75"
-                       "\x82\xa0\x1f\x58\xc6\xd3\x62\xf7"
-                       "\x32\xd8\xaf\x1e\x07\x77\x51\x96"
-                       "\xd5\x6b\x1e\x7e\x80\x02\xe8\x67"
-                       "\xea\x17\x0b\x10\xd2\x3f\x28\x25"
-                       "\x4f\x05\x77\x02\x14\x69\xf0\x2c"
-                       "\xbe\x0c\xf1\x74\x30\xd1\xb9\x9b"
-                       "\xfc\x8c\xbb\x04\x16\xd9\xba\xc3"
-                       "\xbc\x91\x8a\xc4\x30\xa4\xb0\x12"
-                       "\x4c\x21\x87\xcb\xc9\x1d\x16\x96"
-                       "\x07\x6f\x23\x54\xb9\x6f\x79\xe5"
-                       "\x64\xc0\x64\xda\xb1\xae\xdd\x60"
-                       "\x6c\x1a\x9d\xd3\x04\x8e\x45\xb0"
-                       "\x92\x61\xd0\x48\x81\xed\x5e\x1d"
-                       "\xa0\xc9\xa4\x33\xc7\x13\x51\x5d"
-                       "\x7f\x83\x73\xb6\x70\x18\x65\x3e"
-                       "\x2f\x0e\x7a\x12\x39\x98\xab\xd8"
-                       "\x7e\x6f\xa3\xd1\xba\x56\xad\xbd"
-                       "\xf0\x03\x01\x1c\x85\x35\x9f\xeb"
-                       "\x19\x63\xa1\xaf\xfe\x2d\x35\x50"
-                       "\x39\xa0\x65\x7c\x95\x7e\x6b\xfe"
-                       "\xc1\xac\x07\x7c\x98\x4f\xbe\x57"
-                       "\xa7\x22\xec\xe2\x7e\x29\x09\x53"
-                       "\xe8\xbf\xb4\x7e\x3f\x8f\xfc\x14"
-                       "\xce\x54\xf9\x18\x58\xb5\xff\x44"
-                       "\x05\x9d\xce\x1b\xb6\x82\x23\xc8"
-                       "\x2e\xbc\x69\xbb\x4a\x29\x0f\x65"
-                       "\x94\xf0\x63\x06\x0e\xef\x8c\xbd"
-                       "\xff\xfd\xb0\x21\x6e\x57\x05\x75"
-                       "\xda\xd5\xc4\xeb\x8d\x32\xf7\x50"
-                       "\xd3\x6f\x22\xed\x5f\x8e\xa2\x5b"
-                       "\x80\x8c\xc8\x78\x40\x24\x4b\x89"
-                       "\x30\xce\x7a\x97\x0e\xc4\xaf\xef"
-                       "\x9b\xb4\xcd\x66\x74\x14\x04\x2b"
-                       "\xf7\xce\x0b\x1c\x6e\xc2\x78\x8c"
-                       "\xca\xc5\xd0\x1c\x95\x4a\x91\x2d"
-                       "\xa7\x20\xeb\x86\x52\xb7\x67\xd8"
-                       "\x0c\xd6\x04\x14\xde\x51\x74\x75"
-                       "\xe7\x11\xb4\x87\xa3\x3d\x2d\xad"
-                       "\x4f\xef\xa0\x0f\x70\x00\x6d\x13"
-                       "\x19\x1d\x41\x50\xe9\xd8\xf0\x32"
-                       "\x71\xbc\xd3\x11\xf2\xac\xbe\xaf"
-                       "\x75\x46\x65\x4e\x07\x34\x37\xa3"
-                       "\x89\xfe\x75\xd4\x70\x4c\xc6\x3f"
-                       "\x69\x24\x0e\x38\x67\x43\x8c\xde"
-                       "\x06\xb5\xb8\xe7\xc4\xf0\x41\x8f"
-                       "\xf0\xbd\x2f\x0b\xb9\x18\xf8\xde"
-                       "\x64\xb1\xdb\xee\x00\x50\x77\xe1"
-                       "\xc7\xff\xa6\xfa\xdd\x70\xf4\xe3"
-                       "\x93\xe9\x77\x35\x3d\x4b\x2f\x2b"
-                       "\x6d\x55\xf0\xfc\x88\x54\x4e\x89"
-                       "\xc1\x8a\x23\x31\x2d\x14\x2a\xb8"
-                       "\x1b\x15\xdd\x9e\x6e\x7b\xda\x05"
-                       "\x91\x7d\x62\x64\x96\x72\xde\xfc"
-                       "\xc1\xec\xf0\x23\x51\x6f\xdb\x5b"
-                       "\x1d\x08\x57\xce\x09\xb8\xf6\xcd"
-                       "\x8d\x95\xf2\x20\xbf\x0f\x20\x57"
-                       "\x98\x81\x84\x4f\x15\x5c\x76\xe7"
-                       "\x3e\x0a\x3a\x6c\xc4\x8a\xbe\x78"
-                       "\x74\x77\xc3\x09\x4b\x5d\x48\xe4"
-                       "\xc8\xcb\x0b\xea\x17\x28\xcf\xcf"
-                       "\x31\x32\x44\xa4\xe5\x0e\x1a\x98"
-                       "\x94\xc4\xf0\xff\xae\x3e\x44\xe8"
-                       "\xa5\xb3\xb5\x37\x2f\xe8\xaf\x6f"
-                       "\x28\xc1\x37\x5f\x31\xd2\xb9\x33"
-                       "\xb1\xb2\x52\x94\x75\x2c\x29\x59"
-                       "\x06\xc2\x25\xe8\x71\x65\x4e\xed"
-                       "\xc0\x9c\xb1\xbb\x25\xdc\x6c\xe7"
-                       "\x4b\xa5\x7a\x54\x7a\x60\xff\x7a"
-                       "\xe0\x50\x40\x96\x35\x63\xe4\x0b"
-                       "\x76\xbd\xa4\x65\x00\x1b\x57\x88"
-                       "\xae\xed\x39\x88\x42\x11\x3c\xed"
-                       "\x85\x67\x7d\xb9\x68\x82\xe9\x43"
-                       "\x3c\x47\x53\xfa\xe8\xf8\x9f\x1f"
-                       "\x9f\xef\x0f\xf7\x30\xd9\x30\x0e"
-                       "\xb9\x9f\x69\x18\x2f\x7e\xf8\xf8"
-                       "\xf8\x8c\x0f\xd4\x02\x4d\xea\xcd"
-                       "\x0a\x9c\x6f\x71\x6d\x5a\x4c\x60"
-                       "\xce\x20\x56\x32\xc6\xc5\x99\x1f"
-                       "\x09\xe6\x4e\x18\x1a\x15\x13\xa8"
-                       "\x7d\xb1\x6b\xc0\xb2\x6d\xf8\x26"
-                       "\x66\xf8\x3d\x18\x74\x70\x66\x7a"
-                       "\x34\x17\xde\xba\x47\xf1\x06\x18"
-                       "\xcb\xaf\xeb\x4a\x1e\x8f\xa7\x77"
-                       "\xe0\x3b\x78\x62\x66\xc9\x10\xea"
-                       "\x1f\xb7\x29\x0a\x45\xa1\x1d\x1e"
-                       "\x1d\xe2\x65\x61\x50\x9c\xd7\x05"
-                       "\xf2\x0b\x5b\x12\x61\x02\xc8\xe5"
-                       "\x63\x4f\x20\x0c\x07\x17\x33\x5e"
-                       "\x03\x9a\x53\x0f\x2e\x55\xfe\x50"
-                       "\x43\x7d\xd0\xb6\x7e\x5a\xda\xae"
-                       "\x58\xef\x15\xa9\x83\xd9\x46\xb1"
-                       "\x42\xaa\xf5\x02\x6c\xce\x92\x06"
-                       "\x1b\xdb\x66\x45\x91\x79\xc2\x2d"
-                       "\xe6\x53\xd3\x14\xfd\xbb\x44\x63"
-                       "\xc6\xd7\x3d\x7a\x0c\x75\x78\x9d"
-                       "\x5c\xa6\x39\xb3\xe5\x63\xca\x8b"
-                       "\xfe\xd3\xef\x60\x83\xf6\x8e\x70"
-                       "\xb6\x67\xc7\x77\xed\x23\xef\x4c"
-                       "\xf0\xed\x2d\x07\x59\x6f\xc1\x01"
-                       "\x34\x37\x08\xab\xd9\x1f\x09\xb1"
-                       "\xce\x5b\x17\xff\x74\xf8\x9c\xd5"
-                       "\x2c\x56\x39\x79\x0f\x69\x44\x75"
-                       "\x58\x27\x01\xc4\xbf\xa7\xa1\x1d"
-                       "\x90\x17\x77\x86\x5a\x3f\xd9\xd1"
-                       "\x0e\xa0\x10\xf8\xec\x1e\xa5\x7f"
-                       "\x5e\x36\xd1\xe3\x04\x2c\x70\xf7"
-                       "\x8e\xc0\x98\x2f\x6c\x94\x2b\x41"
-                       "\xb7\x60\x00\xb7\x2e\xb8\x02\x8d"
-                       "\xb8\xb0\xd3\x86\xba\x1d\xd7\x90"
-                       "\xd6\xb6\xe1\xfc\xd7\xd8\x28\x06"
-                       "\x63\x9b\xce\x61\x24\x79\xc0\x70"
-                       "\x52\xd0\xb6\xd4\x28\x95\x24\x87"
-                       "\x03\x1f\xb7\x9a\xda\xa3\xfb\x52"
-                       "\x5b\x68\xe7\x4c\x8c\x24\xe1\x42"
-                       "\xf7\xd5\xfd\xad\x06\x32\x9f\xba"
-                       "\xc1\xfc\xdd\xc6\xfc\xfc\xb3\x38"
-                       "\x74\x56\x58\x40\x02\x37\x52\x2c"
-                       "\x55\xcc\xb3\x9e\x7a\xe9\xd4\x38"
-                       "\x41\x5e\x0c\x35\xe2\x11\xd1\x13"
-                       "\xf8\xb7\x8d\x72\x6b\x22\x2a\xb0"
-                       "\xdb\x08\xba\x35\xb9\x3f\xc8\xd3"
-                       "\x24\x90\xec\x58\xd2\x09\xc7\x2d"
-                       "\xed\x38\x80\x36\x72\x43\x27\x49"
-                       "\x4a\x80\x8a\xa2\xe8\xd3\xda\x30"
-                       "\x7d\xb6\x82\x37\x86\x92\x86\x3e"
-                       "\x08\xb2\x28\x5a\x55\x44\x24\x7d"
-                       "\x40\x48\x8a\xb6\x89\x58\x08\xa0"
-                       "\xd6\x6d\x3a\x17\xbf\xf6\x54\xa2"
-                       "\xf5\xd3\x8c\x0f\x78\x12\x57\x8b"
-                       "\xd5\xc2\xfd\x58\x5b\x7f\x38\xe3"
-                       "\xcc\xb7\x7c\x48\xb3\x20\xe8\x81"
-                       "\x14\x32\x45\x05\xe0\xdb\x9f\x75"
-                       "\x85\xb4\x6a\xfc\x95\xe3\x54\x22"
-                       "\x12\xee\x30\xfe\xd8\x30\xef\x34"
-                       "\x50\xab\x46\x30\x98\x2f\xb7\xc0"
-                       "\x15\xa2\x83\xb6\xf2\x06\x21\xa2"
-                       "\xc3\x26\x37\x14\xd1\x4d\xb5\x10"
-                       "\x52\x76\x4d\x6a\xee\xb5\x2b\x15"
-                       "\xb7\xf9\x51\xe8\x2a\xaf\xc7\xfa"
-                       "\x77\xaf\xb0\x05\x4d\xd1\x68\x8e"
-                       "\x74\x05\x9f\x9d\x93\xa5\x3e\x7f"
-                       "\x4e\x5f\x9d\xcb\x09\xc7\x83\xe3"
-                       "\x02\x9d\x27\x1f\xef\x85\x05\x8d"
-                       "\xec\x55\x88\x0f\x0d\x7c\x4c\xe8"
-                       "\xa1\x75\xa0\xd8\x06\x47\x14\xef"
-                       "\xaa\x61\xcf\x26\x15\xad\xd8\xa3"
-                       "\xaa\x75\xf2\x78\x4a\x5a\x61\xdf"
-                       "\x8b\xc7\x04\xbc\xb2\x32\xd2\x7e"
-                       "\x42\xee\xb4\x2f\x51\xff\x7b\x2e"
-                       "\xd3\x02\xe8\xdc\x5d\x0d\x50\xdc"
-                       "\xae\xb7\x46\xf9\xa8\xe6\xd0\x16"
-                       "\xcc\xe6\x2c\x81\xc7\xad\xe9\xf0"
-                       "\x05\x72\x6d\x3d\x0a\x7a\xa9\x02"
-                       "\xac\x82\x93\x6e\xb6\x1c\x28\xfc"
-                       "\x44\x12\xfb\x73\x77\xd4\x13\x39"
-                       "\x29\x88\x8a\xf3\x5c\xa6\x36\xa0"
-                       "\x2a\xed\x7e\xb1\x1d\xd6\x4c\x6b"
-                       "\x41\x01\x18\x5d\x5d\x07\x97\xa6"
-                       "\x4b\xef\x31\x18\xea\xac\xb1\x84"
-                       "\x21\xed\xda\x86",
-               .rlen = 4100,
-       },
-};
-
-static struct cipher_testvec aes_ctr_dec_tv_template[] = {
-       { /* From RFC 3686 */
-               .key    = "\xae\x68\x52\xf8\x12\x10\x67\xcc"
-                         "\x4b\xf7\xa5\x76\x55\x77\xf3\x9e"
-                         "\x00\x00\x00\x30",
-               .klen   = 20,
-               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .input  = "\xe4\x09\x5d\x4f\xb7\xa7\xb3\x79"
-                         "\x2d\x61\x75\xa3\x26\x13\x11\xb8",
-               .ilen   = 16,
-               .result = "Single block msg",
-               .rlen   = 16,
-       }, {
-               .key    = "\x7e\x24\x06\x78\x17\xfa\xe0\xd7"
-                         "\x43\xd6\xce\x1f\x32\x53\x91\x63"
-                         "\x00\x6c\xb6\xdb",
-               .klen   = 20,
-               .iv     = "\xc0\x54\x3b\x59\xda\x48\xd9\x0b",
-               .input  = "\x51\x04\xa1\x06\x16\x8a\x72\xd9"
-                         "\x79\x0d\x41\xee\x8e\xda\xd3\x88"
-                         "\xeb\x2e\x1e\xfc\x46\xda\x57\xc8"
-                         "\xfc\xe6\x30\xdf\x91\x41\xbe\x28",
-               .ilen   = 32,
-               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                         "\x10\x11\x12\x13\x14\x15\x16\x17"
-                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
-               .rlen   = 32,
-       }, {
-               .key    = "\x16\xaf\x5b\x14\x5f\xc9\xf5\x79"
-                         "\xc1\x75\xf9\x3e\x3b\xfb\x0e\xed"
-                         "\x86\x3d\x06\xcc\xfd\xb7\x85\x15"
-                         "\x00\x00\x00\x48",
-               .klen   = 28,
-               .iv     = "\x36\x73\x3c\x14\x7d\x6d\x93\xcb",
-               .input  = "\x4b\x55\x38\x4f\xe2\x59\xc9\xc8"
-                         "\x4e\x79\x35\xa0\x03\xcb\xe9\x28",
-               .ilen   = 16,
-               .result = "Single block msg",
-               .rlen   = 16,
-       }, {
-               .key    = "\x7c\x5c\xb2\x40\x1b\x3d\xc3\x3c"
-                         "\x19\xe7\x34\x08\x19\xe0\xf6\x9c"
-                         "\x67\x8c\x3d\xb8\xe6\xf6\xa9\x1a"
-                         "\x00\x96\xb0\x3b",
-               .klen   = 28,
-               .iv     = "\x02\x0c\x6e\xad\xc2\xcb\x50\x0d",
-               .input  = "\x45\x32\x43\xfc\x60\x9b\x23\x32"
-                         "\x7e\xdf\xaa\xfa\x71\x31\xcd\x9f"
-                         "\x84\x90\x70\x1c\x5a\xd4\xa7\x9c"
-                         "\xfc\x1f\xe0\xff\x42\xf4\xfb\x00",
-               .ilen   = 32,
-               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                         "\x10\x11\x12\x13\x14\x15\x16\x17"
-                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
-               .rlen   = 32,
-       }, { 
-               .key    = "\x77\x6b\xef\xf2\x85\x1d\xb0\x6f"
-                         "\x4c\x8a\x05\x42\xc8\x69\x6f\x6c"
-                         "\x6a\x81\xaf\x1e\xec\x96\xb4\xd3"
-                         "\x7f\xc1\xd6\x89\xe6\xc1\xc1\x04"
-                         "\x00\x00\x00\x60",
-               .klen   = 36,
-               .iv     = "\xdb\x56\x72\xc9\x7a\xa8\xf0\xb2",
-               .input  = "\x14\x5a\xd0\x1d\xbf\x82\x4e\xc7"
-                         "\x56\x08\x63\xdc\x71\xe3\xe0\xc0",
-               .ilen   = 16,
-               .result = "Single block msg",
-               .rlen   = 16,
-       }, {
-               .key    = "\xf6\xd6\x6d\x6b\xd5\x2d\x59\xbb"
-                         "\x07\x96\x36\x58\x79\xef\xf8\x86"
-                         "\xc6\x6d\xd5\x1a\x5b\x6a\x99\x74"
-                         "\x4b\x50\x59\x0c\x87\xa2\x38\x84"
-                         "\x00\xfa\xac\x24",
-               .klen   = 36,
-               .iv     = "\xc1\x58\x5e\xf1\x5a\x43\xd8\x75",
-               .input  = "\xf0\x5e\x23\x1b\x38\x94\x61\x2c"
-                         "\x49\xee\x00\x0b\x80\x4e\xb2\xa9"
-                         "\xb8\x30\x6b\x50\x8f\x83\x9d\x6a"
-                         "\x55\x30\x83\x1d\x93\x44\xaf\x1c",
-               .ilen   = 32,
-               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                         "\x10\x11\x12\x13\x14\x15\x16\x17"
-                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
-               .rlen   = 32,
-       },
-};
-
-static struct aead_testvec aes_gcm_enc_tv_template[] = {
-       { /* From McGrew & Viega - http://citeseer.ist.psu.edu/656989.html */
-               .key    = zeroed_string,
-               .klen   = 16,
-               .result = "\x58\xe2\xfc\xce\xfa\x7e\x30\x61"
-                         "\x36\x7f\x1d\x57\xa4\xe7\x45\x5a",
-               .rlen   = 16,
-       }, {
-               .key    = zeroed_string,
-               .klen   = 16,
-               .input  = zeroed_string,
-               .ilen   = 16,
-               .result = "\x03\x88\xda\xce\x60\xb6\xa3\x92"
-                         "\xf3\x28\xc2\xb9\x71\xb2\xfe\x78"
-                         "\xab\x6e\x47\xd4\x2c\xec\x13\xbd"
-                         "\xf5\x3a\x67\xb2\x12\x57\xbd\xdf",
-               .rlen   = 32,
-       }, {
-               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
-                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08",
-               .klen   = 16,
-               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
-                         "\xde\xca\xf8\x88",
-               .input  = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
-                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
-                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
-                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
-                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
-                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
-                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
-                         "\xba\x63\x7b\x39\x1a\xaf\xd2\x55",
-               .ilen   = 64,
-               .result = "\x42\x83\x1e\xc2\x21\x77\x74\x24"
-                         "\x4b\x72\x21\xb7\x84\xd0\xd4\x9c"
-                         "\xe3\xaa\x21\x2f\x2c\x02\xa4\xe0"
-                         "\x35\xc1\x7e\x23\x29\xac\xa1\x2e"
-                         "\x21\xd5\x14\xb2\x54\x66\x93\x1c"
-                         "\x7d\x8f\x6a\x5a\xac\x84\xaa\x05"
-                         "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97"
-                         "\x3d\x58\xe0\x91\x47\x3f\x59\x85"
-                         "\x4d\x5c\x2a\xf3\x27\xcd\x64\xa6"
-                         "\x2c\xf3\x5a\xbd\x2b\xa6\xfa\xb4",
-               .rlen   = 80,
-       }, {
-               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
-                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08",
-               .klen   = 16,
-               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
-                         "\xde\xca\xf8\x88",
-               .input  = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
-                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
-                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
-                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
-                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
-                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
-                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
-                         "\xba\x63\x7b\x39",
-               .ilen   = 60,
-               .assoc  = "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
-                         "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
-                         "\xab\xad\xda\xd2",
-               .alen   = 20,
-               .result = "\x42\x83\x1e\xc2\x21\x77\x74\x24"
-                         "\x4b\x72\x21\xb7\x84\xd0\xd4\x9c"
-                         "\xe3\xaa\x21\x2f\x2c\x02\xa4\xe0"
-                         "\x35\xc1\x7e\x23\x29\xac\xa1\x2e"
-                         "\x21\xd5\x14\xb2\x54\x66\x93\x1c"
-                         "\x7d\x8f\x6a\x5a\xac\x84\xaa\x05"
-                         "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97"
-                         "\x3d\x58\xe0\x91"
-                         "\x5b\xc9\x4f\xbc\x32\x21\xa5\xdb"
-                         "\x94\xfa\xe9\x5a\xe7\x12\x1a\x47",
-               .rlen   = 76,
-       }, {
-               .key    = zeroed_string,
-               .klen   = 24,
-               .result = "\xcd\x33\xb2\x8a\xc7\x73\xf7\x4b"
-                         "\xa0\x0e\xd1\xf3\x12\x57\x24\x35",
-               .rlen   = 16,
-       }, {
-               .key    = zeroed_string,
-               .klen   = 24,
-               .input  = zeroed_string,
-               .ilen   = 16,
-               .result = "\x98\xe7\x24\x7c\x07\xf0\xfe\x41"
-                         "\x1c\x26\x7e\x43\x84\xb0\xf6\x00"
-                         "\x2f\xf5\x8d\x80\x03\x39\x27\xab"
-                         "\x8e\xf4\xd4\x58\x75\x14\xf0\xfb",
-               .rlen   = 32,
-       }, {
-               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
-                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
-                         "\xfe\xff\xe9\x92\x86\x65\x73\x1c",
-               .klen   = 24,
-               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
-                         "\xde\xca\xf8\x88",
-               .input  = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
-                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
-                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
-                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
-                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
-                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
-                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
-                         "\xba\x63\x7b\x39\x1a\xaf\xd2\x55",
-               .ilen   = 64,
-               .result = "\x39\x80\xca\x0b\x3c\x00\xe8\x41"
-                         "\xeb\x06\xfa\xc4\x87\x2a\x27\x57"
-                         "\x85\x9e\x1c\xea\xa6\xef\xd9\x84"
-                         "\x62\x85\x93\xb4\x0c\xa1\xe1\x9c"
-                         "\x7d\x77\x3d\x00\xc1\x44\xc5\x25"
-                         "\xac\x61\x9d\x18\xc8\x4a\x3f\x47"
-                         "\x18\xe2\x44\x8b\x2f\xe3\x24\xd9"
-                         "\xcc\xda\x27\x10\xac\xad\xe2\x56"
-                         "\x99\x24\xa7\xc8\x58\x73\x36\xbf"
-                         "\xb1\x18\x02\x4d\xb8\x67\x4a\x14",
-               .rlen   = 80,
-       }, {
-               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
-                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
-                         "\xfe\xff\xe9\x92\x86\x65\x73\x1c",
-               .klen   = 24,
-               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
-                         "\xde\xca\xf8\x88",
-               .input  = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
-                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
-                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
-                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
-                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
-                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
-                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
-                         "\xba\x63\x7b\x39",
-               .ilen   = 60,
-               .assoc  = "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
-                         "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
-                         "\xab\xad\xda\xd2",
-               .alen   = 20,
-               .result = "\x39\x80\xca\x0b\x3c\x00\xe8\x41"
-                         "\xeb\x06\xfa\xc4\x87\x2a\x27\x57"
-                         "\x85\x9e\x1c\xea\xa6\xef\xd9\x84"
-                         "\x62\x85\x93\xb4\x0c\xa1\xe1\x9c"
-                         "\x7d\x77\x3d\x00\xc1\x44\xc5\x25"
-                         "\xac\x61\x9d\x18\xc8\x4a\x3f\x47"
-                         "\x18\xe2\x44\x8b\x2f\xe3\x24\xd9"
-                         "\xcc\xda\x27\x10"
-                         "\x25\x19\x49\x8e\x80\xf1\x47\x8f"
-                         "\x37\xba\x55\xbd\x6d\x27\x61\x8c",
-               .rlen   = 76,
-               .np     = 2,
-               .tap    = { 32, 28 },
-               .anp    = 2,
-               .atap   = { 8, 12 }
-       }, {
-               .key    = zeroed_string,
-               .klen   = 32,
-               .result = "\x53\x0f\x8a\xfb\xc7\x45\x36\xb9"
-                         "\xa9\x63\xb4\xf1\xc4\xcb\x73\x8b",
-               .rlen   = 16,
-       }
-};
-
-static struct aead_testvec aes_gcm_dec_tv_template[] = {
-       { /* From McGrew & Viega - http://citeseer.ist.psu.edu/656989.html */
-               .key    = zeroed_string,
-               .klen   = 32,
-               .input  = "\xce\xa7\x40\x3d\x4d\x60\x6b\x6e"
-                         "\x07\x4e\xc5\xd3\xba\xf3\x9d\x18"
-                         "\xd0\xd1\xc8\xa7\x99\x99\x6b\xf0"
-                         "\x26\x5b\x98\xb5\xd4\x8a\xb9\x19",
-               .ilen   = 32,
-               .result  = zeroed_string,
-               .rlen   = 16,
-       }, {
-               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
-                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
-                         "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
-                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08",
-               .klen   = 32,
-               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
-                         "\xde\xca\xf8\x88",
-               .input  = "\x52\x2d\xc1\xf0\x99\x56\x7d\x07"
-                         "\xf4\x7f\x37\xa3\x2a\x84\x42\x7d"
-                         "\x64\x3a\x8c\xdc\xbf\xe5\xc0\xc9"
-                         "\x75\x98\xa2\xbd\x25\x55\xd1\xaa"
-                         "\x8c\xb0\x8e\x48\x59\x0d\xbb\x3d"
-                         "\xa7\xb0\x8b\x10\x56\x82\x88\x38"
-                         "\xc5\xf6\x1e\x63\x93\xba\x7a\x0a"
-                         "\xbc\xc9\xf6\x62\x89\x80\x15\xad"
-                         "\xb0\x94\xda\xc5\xd9\x34\x71\xbd"
-                         "\xec\x1a\x50\x22\x70\xe3\xcc\x6c",
-               .ilen   = 80,
-               .result = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
-                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
-                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
-                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
-                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
-                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
-                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
-                         "\xba\x63\x7b\x39\x1a\xaf\xd2\x55",
-               .rlen   = 64,
-       }, {
-               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
-                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
-                         "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
-                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08",
-               .klen   = 32,
-               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
-                         "\xde\xca\xf8\x88",
-               .input  = "\x52\x2d\xc1\xf0\x99\x56\x7d\x07"
-                         "\xf4\x7f\x37\xa3\x2a\x84\x42\x7d"
-                         "\x64\x3a\x8c\xdc\xbf\xe5\xc0\xc9"
-                         "\x75\x98\xa2\xbd\x25\x55\xd1\xaa"
-                         "\x8c\xb0\x8e\x48\x59\x0d\xbb\x3d"
-                         "\xa7\xb0\x8b\x10\x56\x82\x88\x38"
-                         "\xc5\xf6\x1e\x63\x93\xba\x7a\x0a"
-                         "\xbc\xc9\xf6\x62"
-                         "\x76\xfc\x6e\xce\x0f\x4e\x17\x68"
-                         "\xcd\xdf\x88\x53\xbb\x2d\x55\x1b",
-               .ilen   = 76,
-               .assoc  = "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
-                         "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
-                         "\xab\xad\xda\xd2",
-               .alen   = 20,
-               .result = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
-                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
-                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
-                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
-                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
-                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
-                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
-                         "\xba\x63\x7b\x39",
-               .rlen   = 60,
-               .np     = 2,
-               .tap    = { 48, 28 },
-               .anp    = 3,
-               .atap   = { 8, 8, 4 }
-       }, {
-               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
-                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08",
-               .klen   = 16,
-               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
-                         "\xde\xca\xf8\x88",
-               .input  = "\x42\x83\x1e\xc2\x21\x77\x74\x24"
-                         "\x4b\x72\x21\xb7\x84\xd0\xd4\x9c"
-                         "\xe3\xaa\x21\x2f\x2c\x02\xa4\xe0"
-                         "\x35\xc1\x7e\x23\x29\xac\xa1\x2e"
-                         "\x21\xd5\x14\xb2\x54\x66\x93\x1c"
-                         "\x7d\x8f\x6a\x5a\xac\x84\xaa\x05"
-                         "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97"
-                         "\x3d\x58\xe0\x91\x47\x3f\x59\x85"
-                         "\x4d\x5c\x2a\xf3\x27\xcd\x64\xa6"
-                         "\x2c\xf3\x5a\xbd\x2b\xa6\xfa\xb4",
-               .ilen   = 80,
-               .result = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
-                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
-                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
-                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
-                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
-                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
-                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
-                         "\xba\x63\x7b\x39\x1a\xaf\xd2\x55",
-               .rlen   = 64,
-       }, {
-               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
-                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08",
-               .klen   = 16,
-               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
-                         "\xde\xca\xf8\x88",
-               .input  = "\x42\x83\x1e\xc2\x21\x77\x74\x24"
-                         "\x4b\x72\x21\xb7\x84\xd0\xd4\x9c"
-                         "\xe3\xaa\x21\x2f\x2c\x02\xa4\xe0"
-                         "\x35\xc1\x7e\x23\x29\xac\xa1\x2e"
-                         "\x21\xd5\x14\xb2\x54\x66\x93\x1c"
-                         "\x7d\x8f\x6a\x5a\xac\x84\xaa\x05"
-                         "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97"
-                         "\x3d\x58\xe0\x91"
-                         "\x5b\xc9\x4f\xbc\x32\x21\xa5\xdb"
-                         "\x94\xfa\xe9\x5a\xe7\x12\x1a\x47",
-               .ilen   = 76,
-               .assoc  = "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
-                         "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
-                         "\xab\xad\xda\xd2",
-               .alen   = 20,
-               .result = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
-                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
-                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
-                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
-                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
-                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
-                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
-                         "\xba\x63\x7b\x39",
-               .rlen   = 60,
-       }, {
-               .key    = zeroed_string,
-               .klen   = 24,
-               .input  = "\x98\xe7\x24\x7c\x07\xf0\xfe\x41"
-                         "\x1c\x26\x7e\x43\x84\xb0\xf6\x00"
-                         "\x2f\xf5\x8d\x80\x03\x39\x27\xab"
-                         "\x8e\xf4\xd4\x58\x75\x14\xf0\xfb",
-               .ilen   = 32,
-               .result  = zeroed_string,
-               .rlen   = 16,
-       }, {
-               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
-                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
-                         "\xfe\xff\xe9\x92\x86\x65\x73\x1c",
-               .klen   = 24,
-               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
-                         "\xde\xca\xf8\x88",
-               .input  = "\x39\x80\xca\x0b\x3c\x00\xe8\x41"
-                         "\xeb\x06\xfa\xc4\x87\x2a\x27\x57"
-                         "\x85\x9e\x1c\xea\xa6\xef\xd9\x84"
-                         "\x62\x85\x93\xb4\x0c\xa1\xe1\x9c"
-                         "\x7d\x77\x3d\x00\xc1\x44\xc5\x25"
-                         "\xac\x61\x9d\x18\xc8\x4a\x3f\x47"
-                         "\x18\xe2\x44\x8b\x2f\xe3\x24\xd9"
-                         "\xcc\xda\x27\x10\xac\xad\xe2\x56"
-                         "\x99\x24\xa7\xc8\x58\x73\x36\xbf"
-                         "\xb1\x18\x02\x4d\xb8\x67\x4a\x14",
-               .ilen   = 80,
-               .result = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
-                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
-                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
-                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
-                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
-                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
-                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
-                         "\xba\x63\x7b\x39\x1a\xaf\xd2\x55",
-               .rlen   = 64,
-       }, {
-               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
-                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
-                         "\xfe\xff\xe9\x92\x86\x65\x73\x1c",
-               .klen   = 24,
-               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
-                         "\xde\xca\xf8\x88",
-               .input  = "\x39\x80\xca\x0b\x3c\x00\xe8\x41"
-                         "\xeb\x06\xfa\xc4\x87\x2a\x27\x57"
-                         "\x85\x9e\x1c\xea\xa6\xef\xd9\x84"
-                         "\x62\x85\x93\xb4\x0c\xa1\xe1\x9c"
-                         "\x7d\x77\x3d\x00\xc1\x44\xc5\x25"
-                         "\xac\x61\x9d\x18\xc8\x4a\x3f\x47"
-                         "\x18\xe2\x44\x8b\x2f\xe3\x24\xd9"
-                         "\xcc\xda\x27\x10"
-                         "\x25\x19\x49\x8e\x80\xf1\x47\x8f"
-                         "\x37\xba\x55\xbd\x6d\x27\x61\x8c",
-               .ilen   = 76,
-               .assoc  = "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
-                         "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
-                         "\xab\xad\xda\xd2",
-               .alen   = 20,
-               .result = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
-                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
-                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
-                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
-                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
-                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
-                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
-                         "\xba\x63\x7b\x39",
-               .rlen   = 60,
-       }
-};
-
-static struct aead_testvec aes_ccm_enc_tv_template[] = {
-       { /* From RFC 3610 */
-               .key    = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
-                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
-               .klen   = 16,
-               .iv     = "\x01\x00\x00\x00\x03\x02\x01\x00"
-                         "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
-               .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07",
-               .alen   = 8,
-               .input  = "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                         "\x10\x11\x12\x13\x14\x15\x16\x17"
-                         "\x18\x19\x1a\x1b\x1c\x1d\x1e",
-               .ilen   = 23,
-               .result = "\x58\x8c\x97\x9a\x61\xc6\x63\xd2"
-                         "\xf0\x66\xd0\xc2\xc0\xf9\x89\x80"
-                         "\x6d\x5f\x6b\x61\xda\xc3\x84\x17"
-                         "\xe8\xd1\x2c\xfd\xf9\x26\xe0",
-               .rlen   = 31,
-       }, {
-               .key    = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
-                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
-               .klen   = 16,
-               .iv     = "\x01\x00\x00\x00\x07\x06\x05\x04"
-                         "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
-               .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b",
-               .alen   = 12,
-               .input  = "\x0c\x0d\x0e\x0f\x10\x11\x12\x13"
-                         "\x14\x15\x16\x17\x18\x19\x1a\x1b"
-                         "\x1c\x1d\x1e\x1f",
-               .ilen   = 20,
-               .result = "\xdc\xf1\xfb\x7b\x5d\x9e\x23\xfb"
-                         "\x9d\x4e\x13\x12\x53\x65\x8a\xd8"
-                         "\x6e\xbd\xca\x3e\x51\xe8\x3f\x07"
-                         "\x7d\x9c\x2d\x93",
-               .rlen   = 28,
-       }, {
-               .key    = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
-                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
-               .klen   = 16,
-               .iv     = "\x01\x00\x00\x00\x0b\x0a\x09\x08"
-                         "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
-               .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07",
-               .alen   = 8,
-               .input  = "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                         "\x10\x11\x12\x13\x14\x15\x16\x17"
-                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
-                         "\x20",
-               .ilen   = 25,
-               .result = "\x82\x53\x1a\x60\xcc\x24\x94\x5a"
-                         "\x4b\x82\x79\x18\x1a\xb5\xc8\x4d"
-                         "\xf2\x1c\xe7\xf9\xb7\x3f\x42\xe1"
-                         "\x97\xea\x9c\x07\xe5\x6b\x5e\xb1"
-                         "\x7e\x5f\x4e",
-               .rlen   = 35,
-       }, {
-               .key    = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
-                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
-               .klen   = 16,
-               .iv     = "\x01\x00\x00\x00\x0c\x0b\x0a\x09"
-                         "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
-               .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b",
-               .alen   = 12,
-               .input  = "\x0c\x0d\x0e\x0f\x10\x11\x12\x13"
-                         "\x14\x15\x16\x17\x18\x19\x1a\x1b"
-                         "\x1c\x1d\x1e",
-               .ilen   = 19,
-               .result = "\x07\x34\x25\x94\x15\x77\x85\x15"
-                         "\x2b\x07\x40\x98\x33\x0a\xbb\x14"
-                         "\x1b\x94\x7b\x56\x6a\xa9\x40\x6b"
-                         "\x4d\x99\x99\x88\xdd",
-               .rlen   = 29,
-       }, {
-               .key    = "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3"
-                         "\x25\xa7\x62\x36\xdf\x93\xcc\x6b",
-               .klen   = 16,
-               .iv     = "\x01\x00\x33\x56\x8e\xf7\xb2\x63"
-                         "\x3c\x96\x96\x76\x6c\xfa\x00\x00",
-               .assoc  = "\x63\x01\x8f\x76\xdc\x8a\x1b\xcb",
-               .alen   = 8,
-               .input  = "\x90\x20\xea\x6f\x91\xbd\xd8\x5a"
-                         "\xfa\x00\x39\xba\x4b\xaf\xf9\xbf"
-                         "\xb7\x9c\x70\x28\x94\x9c\xd0\xec",
-               .ilen   = 24,
-               .result = "\x4c\xcb\x1e\x7c\xa9\x81\xbe\xfa"
-                         "\xa0\x72\x6c\x55\xd3\x78\x06\x12"
-                         "\x98\xc8\x5c\x92\x81\x4a\xbc\x33"
-                         "\xc5\x2e\xe8\x1d\x7d\x77\xc0\x8a",
-               .rlen   = 32,
-       }, {
-               .key    = "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3"
-                         "\x25\xa7\x62\x36\xdf\x93\xcc\x6b",
-               .klen   = 16,
-               .iv     = "\x01\x00\xd5\x60\x91\x2d\x3f\x70"
-                         "\x3c\x96\x96\x76\x6c\xfa\x00\x00",
-               .assoc  = "\xcd\x90\x44\xd2\xb7\x1f\xdb\x81"
-                         "\x20\xea\x60\xc0",
-               .alen   = 12,
-               .input  = "\x64\x35\xac\xba\xfb\x11\xa8\x2e"
-                         "\x2f\x07\x1d\x7c\xa4\xa5\xeb\xd9"
-                         "\x3a\x80\x3b\xa8\x7f",
-               .ilen   = 21,
-               .result = "\x00\x97\x69\xec\xab\xdf\x48\x62"
-                         "\x55\x94\xc5\x92\x51\xe6\x03\x57"
-                         "\x22\x67\x5e\x04\xc8\x47\x09\x9e"
-                         "\x5a\xe0\x70\x45\x51",
-               .rlen   = 29,
-       }, {
-               .key    = "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3"
-                         "\x25\xa7\x62\x36\xdf\x93\xcc\x6b",
-               .klen   = 16,
-               .iv     = "\x01\x00\x42\xff\xf8\xf1\x95\x1c"
-                         "\x3c\x96\x96\x76\x6c\xfa\x00\x00",
-               .assoc  = "\xd8\x5b\xc7\xe6\x9f\x94\x4f\xb8",
-               .alen   = 8,
-               .input  = "\x8a\x19\xb9\x50\xbc\xf7\x1a\x01"
-                         "\x8e\x5e\x67\x01\xc9\x17\x87\x65"
-                         "\x98\x09\xd6\x7d\xbe\xdd\x18",
-               .ilen   = 23,
-               .result = "\xbc\x21\x8d\xaa\x94\x74\x27\xb6"
-                         "\xdb\x38\x6a\x99\xac\x1a\xef\x23"
-                         "\xad\xe0\xb5\x29\x39\xcb\x6a\x63"
-                         "\x7c\xf9\xbe\xc2\x40\x88\x97\xc6"
-                         "\xba",
-               .rlen   = 33,
-       },
-};
-
-static struct aead_testvec aes_ccm_dec_tv_template[] = {
-       { /* From RFC 3610 */
-               .key    = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
-                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
-               .klen   = 16,
-               .iv     = "\x01\x00\x00\x00\x03\x02\x01\x00"
-                         "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
-               .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07",
-               .alen   = 8,
-               .input  = "\x58\x8c\x97\x9a\x61\xc6\x63\xd2"
-                         "\xf0\x66\xd0\xc2\xc0\xf9\x89\x80"
-                         "\x6d\x5f\x6b\x61\xda\xc3\x84\x17"
-                         "\xe8\xd1\x2c\xfd\xf9\x26\xe0",
-               .ilen   = 31,
-               .result = "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                         "\x10\x11\x12\x13\x14\x15\x16\x17"
-                         "\x18\x19\x1a\x1b\x1c\x1d\x1e",
-               .rlen   = 23,
-       }, {
-               .key    = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
-                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
-               .klen   = 16,
-               .iv     = "\x01\x00\x00\x00\x07\x06\x05\x04"
-                         "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
-               .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b",
-               .alen   = 12,
-               .input  = "\xdc\xf1\xfb\x7b\x5d\x9e\x23\xfb"
-                         "\x9d\x4e\x13\x12\x53\x65\x8a\xd8"
-                         "\x6e\xbd\xca\x3e\x51\xe8\x3f\x07"
-                         "\x7d\x9c\x2d\x93",
-               .ilen   = 28,
-               .result = "\x0c\x0d\x0e\x0f\x10\x11\x12\x13"
-                         "\x14\x15\x16\x17\x18\x19\x1a\x1b"
-                         "\x1c\x1d\x1e\x1f",
-               .rlen   = 20,
-       }, {
-               .key    = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
-                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
-               .klen   = 16,
-               .iv     = "\x01\x00\x00\x00\x0b\x0a\x09\x08"
-                         "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
-               .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07",
-               .alen   = 8,
-               .input  = "\x82\x53\x1a\x60\xcc\x24\x94\x5a"
-                         "\x4b\x82\x79\x18\x1a\xb5\xc8\x4d"
-                         "\xf2\x1c\xe7\xf9\xb7\x3f\x42\xe1"
-                         "\x97\xea\x9c\x07\xe5\x6b\x5e\xb1"
-                         "\x7e\x5f\x4e",
-               .ilen   = 35,
-               .result = "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                         "\x10\x11\x12\x13\x14\x15\x16\x17"
-                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
-                         "\x20",
-               .rlen   = 25,
-       }, {
-               .key    = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
-                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
-               .klen   = 16,
-               .iv     = "\x01\x00\x00\x00\x0c\x0b\x0a\x09"
-                         "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
-               .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b",
-               .alen   = 12,
-               .input  = "\x07\x34\x25\x94\x15\x77\x85\x15"
-                         "\x2b\x07\x40\x98\x33\x0a\xbb\x14"
-                         "\x1b\x94\x7b\x56\x6a\xa9\x40\x6b"
-                         "\x4d\x99\x99\x88\xdd",
-               .ilen   = 29,
-               .result = "\x0c\x0d\x0e\x0f\x10\x11\x12\x13"
-                         "\x14\x15\x16\x17\x18\x19\x1a\x1b"
-                         "\x1c\x1d\x1e",
-               .rlen   = 19,
-       }, {
-               .key    = "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3"
-                         "\x25\xa7\x62\x36\xdf\x93\xcc\x6b",
-               .klen   = 16,
-               .iv     = "\x01\x00\x33\x56\x8e\xf7\xb2\x63"
-                         "\x3c\x96\x96\x76\x6c\xfa\x00\x00",
-               .assoc  = "\x63\x01\x8f\x76\xdc\x8a\x1b\xcb",
-               .alen   = 8,
-               .input  = "\x4c\xcb\x1e\x7c\xa9\x81\xbe\xfa"
-                         "\xa0\x72\x6c\x55\xd3\x78\x06\x12"
-                         "\x98\xc8\x5c\x92\x81\x4a\xbc\x33"
-                         "\xc5\x2e\xe8\x1d\x7d\x77\xc0\x8a",
-               .ilen   = 32,
-               .result = "\x90\x20\xea\x6f\x91\xbd\xd8\x5a"
-                         "\xfa\x00\x39\xba\x4b\xaf\xf9\xbf"
-                         "\xb7\x9c\x70\x28\x94\x9c\xd0\xec",
-               .rlen   = 24,
-       }, {
-               .key    = "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3"
-                         "\x25\xa7\x62\x36\xdf\x93\xcc\x6b",
-               .klen   = 16,
-               .iv     = "\x01\x00\xd5\x60\x91\x2d\x3f\x70"
-                         "\x3c\x96\x96\x76\x6c\xfa\x00\x00",
-               .assoc  = "\xcd\x90\x44\xd2\xb7\x1f\xdb\x81"
-                         "\x20\xea\x60\xc0",
-               .alen   = 12,
-               .input  = "\x00\x97\x69\xec\xab\xdf\x48\x62"
-                         "\x55\x94\xc5\x92\x51\xe6\x03\x57"
-                         "\x22\x67\x5e\x04\xc8\x47\x09\x9e"
-                         "\x5a\xe0\x70\x45\x51",
-               .ilen   = 29,
-               .result = "\x64\x35\xac\xba\xfb\x11\xa8\x2e"
-                         "\x2f\x07\x1d\x7c\xa4\xa5\xeb\xd9"
-                         "\x3a\x80\x3b\xa8\x7f",
-               .rlen   = 21,
-       }, {
-               .key    = "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3"
-                         "\x25\xa7\x62\x36\xdf\x93\xcc\x6b",
-               .klen   = 16,
-               .iv     = "\x01\x00\x42\xff\xf8\xf1\x95\x1c"
-                         "\x3c\x96\x96\x76\x6c\xfa\x00\x00",
-               .assoc  = "\xd8\x5b\xc7\xe6\x9f\x94\x4f\xb8",
-               .alen   = 8,
-               .input  = "\xbc\x21\x8d\xaa\x94\x74\x27\xb6"
-                         "\xdb\x38\x6a\x99\xac\x1a\xef\x23"
-                         "\xad\xe0\xb5\x29\x39\xcb\x6a\x63"
-                         "\x7c\xf9\xbe\xc2\x40\x88\x97\xc6"
-                         "\xba",
-               .ilen   = 33,
-               .result = "\x8a\x19\xb9\x50\xbc\xf7\x1a\x01"
-                         "\x8e\x5e\x67\x01\xc9\x17\x87\x65"
-                         "\x98\x09\xd6\x7d\xbe\xdd\x18",
-               .rlen   = 23,
-       },
-};
-
-/* Cast5 test vectors from RFC 2144 */
-#define CAST5_ENC_TEST_VECTORS 3
-#define CAST5_DEC_TEST_VECTORS 3
-
-static struct cipher_testvec cast5_enc_tv_template[] = {
-       {
-               .key    = "\x01\x23\x45\x67\x12\x34\x56\x78"
-                         "\x23\x45\x67\x89\x34\x56\x78\x9a",
-               .klen   = 16,
-               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .ilen   = 8,
-               .result = "\x23\x8b\x4f\xe5\x84\x7e\x44\xb2",
-               .rlen   = 8,
-       }, {
-               .key    = "\x01\x23\x45\x67\x12\x34\x56\x78"
-                         "\x23\x45",
-               .klen   = 10,
-               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .ilen   = 8,
-               .result = "\xeb\x6a\x71\x1a\x2c\x02\x27\x1b",
-               .rlen   = 8,
-       }, {
-               .key    = "\x01\x23\x45\x67\x12",
-               .klen   = 5,
-               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .ilen   = 8,
-               .result = "\x7a\xc8\x16\xd1\x6e\x9b\x30\x2e",
-               .rlen   = 8,
-       },
-};
-
-static struct cipher_testvec cast5_dec_tv_template[] = {
-       {
-               .key    = "\x01\x23\x45\x67\x12\x34\x56\x78"
-                         "\x23\x45\x67\x89\x34\x56\x78\x9a",
-               .klen   = 16,
-               .input  = "\x23\x8b\x4f\xe5\x84\x7e\x44\xb2",
-               .ilen   = 8,
-               .result = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .rlen   = 8,
-       }, {
-               .key    = "\x01\x23\x45\x67\x12\x34\x56\x78"
-                         "\x23\x45",
-               .klen   = 10,
-               .input  = "\xeb\x6a\x71\x1a\x2c\x02\x27\x1b",
-               .ilen   = 8,
-               .result = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .rlen   = 8,
-       }, {
-               .key    = "\x01\x23\x45\x67\x12",
-               .klen   = 5,
-               .input  = "\x7a\xc8\x16\xd1\x6e\x9b\x30\x2e",
-               .ilen   = 8,
-               .result = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .rlen   = 8,
-       },
-};
-
-/*
- * ARC4 test vectors from OpenSSL
- */
-#define ARC4_ENC_TEST_VECTORS  7
-#define ARC4_DEC_TEST_VECTORS  7
-
-static struct cipher_testvec arc4_enc_tv_template[] = {
-       {
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .klen   = 8,
-               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .ilen   = 8,
-               .result = "\x75\xb7\x87\x80\x99\xe0\xc5\x96",
-               .rlen   = 8,
-       }, {
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .klen   = 8,
-               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .ilen   = 8,
-               .result = "\x74\x94\xc2\xe7\x10\x4b\x08\x79",
-               .rlen   = 8,
-       }, {
-               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .klen   = 8,
-               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .ilen   = 8,
-               .result = "\xde\x18\x89\x41\xa3\x37\x5d\x3a",
-               .rlen   = 8,
-       }, {
-               .key    = "\xef\x01\x23\x45",
-               .klen   = 4,
-               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00",
-               .ilen   = 20,
-               .result = "\xd6\xa1\x41\xa7\xec\x3c\x38\xdf"
-                         "\xbd\x61\x5a\x11\x62\xe1\xc7\xba"
-                         "\x36\xb6\x78\x58",
-               .rlen   = 20,
-       }, {
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .klen   = 8,
-               .input  = "\x12\x34\x56\x78\x9A\xBC\xDE\xF0"
-                         "\x12\x34\x56\x78\x9A\xBC\xDE\xF0"
-                         "\x12\x34\x56\x78\x9A\xBC\xDE\xF0"
-                         "\x12\x34\x56\x78",
-               .ilen   = 28,
-               .result = "\x66\xa0\x94\x9f\x8a\xf7\xd6\x89"
-                         "\x1f\x7f\x83\x2b\xa8\x33\xc0\x0c"
-                         "\x89\x2e\xbe\x30\x14\x3c\xe2\x87"
-                         "\x40\x01\x1e\xcf",
-               .rlen   = 28,
-       }, {
-               .key    = "\xef\x01\x23\x45",
-               .klen   = 4,
-               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00",
-               .ilen   = 10,
-               .result = "\xd6\xa1\x41\xa7\xec\x3c\x38\xdf"
-                         "\xbd\x61",
-               .rlen   = 10,
-       }, {
-               .key    = "\x01\x23\x45\x67\x89\xAB\xCD\xEF"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .klen   = 16,
-               .input  = "\x01\x23\x45\x67\x89\xAB\xCD\xEF",
-               .ilen   = 8,
-               .result = "\x69\x72\x36\x59\x1B\x52\x42\xB1",
-               .rlen   = 8,
-       },
-};
-
-static struct cipher_testvec arc4_dec_tv_template[] = {
-       {
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .klen   = 8,
-               .input  = "\x75\xb7\x87\x80\x99\xe0\xc5\x96",
-               .ilen   = 8,
-               .result = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .rlen   = 8,
-       }, {
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .klen   = 8,
-               .input  = "\x74\x94\xc2\xe7\x10\x4b\x08\x79",
-               .ilen   = 8,
-               .result = "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .rlen   = 8,
-       }, {
-               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .klen   = 8,
-               .input  = "\xde\x18\x89\x41\xa3\x37\x5d\x3a",
-               .ilen   = 8,
-               .result = "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .rlen   = 8,
-       }, {
-               .key    = "\xef\x01\x23\x45",
-               .klen   = 4,
-               .input  = "\xd6\xa1\x41\xa7\xec\x3c\x38\xdf"
-                         "\xbd\x61\x5a\x11\x62\xe1\xc7\xba"
-                         "\x36\xb6\x78\x58",
-               .ilen   = 20,
-               .result = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00",
-               .rlen   = 20,
-       }, {
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
-               .klen   = 8,
-               .input  = "\x66\xa0\x94\x9f\x8a\xf7\xd6\x89"
-                         "\x1f\x7f\x83\x2b\xa8\x33\xc0\x0c"
-                         "\x89\x2e\xbe\x30\x14\x3c\xe2\x87"
-                         "\x40\x01\x1e\xcf",
-               .ilen   = 28,
-               .result = "\x12\x34\x56\x78\x9A\xBC\xDE\xF0"
-                         "\x12\x34\x56\x78\x9A\xBC\xDE\xF0"
-                         "\x12\x34\x56\x78\x9A\xBC\xDE\xF0"
-                         "\x12\x34\x56\x78",
-               .rlen   = 28,
-       }, {
-               .key    = "\xef\x01\x23\x45",
-               .klen   = 4,
-               .input  = "\xd6\xa1\x41\xa7\xec\x3c\x38\xdf"
-                         "\xbd\x61",
-               .ilen   = 10,
-               .result = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00",
-               .rlen   = 10,
-       }, {
-               .key    = "\x01\x23\x45\x67\x89\xAB\xCD\xEF"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .klen   = 16,
-               .input  = "\x69\x72\x36\x59\x1B\x52\x42\xB1",
-               .ilen   = 8,
-               .result = "\x01\x23\x45\x67\x89\xAB\xCD\xEF",
-               .rlen   = 8,
-       },
-};
-
-/*
- * TEA test vectors
- */
-#define TEA_ENC_TEST_VECTORS   4
-#define TEA_DEC_TEST_VECTORS   4
-
-static struct cipher_testvec tea_enc_tv_template[] = {
-       {
-               .key    = zeroed_string,
-               .klen   = 16,
-               .input  = zeroed_string,
-               .ilen   = 8,
-               .result = "\x0a\x3a\xea\x41\x40\xa9\xba\x94",
-               .rlen   = 8,
-       }, {
-               .key    = "\x2b\x02\x05\x68\x06\x14\x49\x76"
-                         "\x77\x5d\x0e\x26\x6c\x28\x78\x43",
-               .klen   = 16,
-               .input  = "\x74\x65\x73\x74\x20\x6d\x65\x2e",
-               .ilen   = 8,
-               .result = "\x77\x5d\x2a\x6a\xf6\xce\x92\x09",
-               .rlen   = 8,
-       }, {
-               .key    = "\x09\x65\x43\x11\x66\x44\x39\x25"
-                         "\x51\x3a\x16\x10\x0a\x08\x12\x6e",
-               .klen   = 16,
-               .input  = "\x6c\x6f\x6e\x67\x65\x72\x5f\x74"
-                         "\x65\x73\x74\x5f\x76\x65\x63\x74",
-               .ilen   = 16,
-               .result = "\xbe\x7a\xbb\x81\x95\x2d\x1f\x1e"
-                         "\xdd\x89\xa1\x25\x04\x21\xdf\x95",
-               .rlen   = 16,
-       }, {
-               .key    = "\x4d\x76\x32\x17\x05\x3f\x75\x2c"
-                         "\x5d\x04\x16\x36\x15\x72\x63\x2f",
-               .klen   = 16,
-               .input  = "\x54\x65\x61\x20\x69\x73\x20\x67"
-                         "\x6f\x6f\x64\x20\x66\x6f\x72\x20"
-                         "\x79\x6f\x75\x21\x21\x21\x20\x72"
-                         "\x65\x61\x6c\x6c\x79\x21\x21\x21",
-               .ilen   = 32,
-               .result = "\xe0\x4d\x5d\x3c\xb7\x8c\x36\x47"
-                         "\x94\x18\x95\x91\xa9\xfc\x49\xf8"
-                         "\x44\xd1\x2d\xc2\x99\xb8\x08\x2a"
-                         "\x07\x89\x73\xc2\x45\x92\xc6\x90",
-               .rlen   = 32,
-       }
-};
-
-static struct cipher_testvec tea_dec_tv_template[] = {
-       {
-               .key    = zeroed_string,
-               .klen   = 16,
-               .input  = "\x0a\x3a\xea\x41\x40\xa9\xba\x94",
-               .ilen   = 8,
-               .result = zeroed_string,
-               .rlen   = 8,
-       }, {
-               .key    = "\x2b\x02\x05\x68\x06\x14\x49\x76"
-                         "\x77\x5d\x0e\x26\x6c\x28\x78\x43",
-               .klen   = 16,
-               .input  = "\x77\x5d\x2a\x6a\xf6\xce\x92\x09",
-               .ilen   = 8,
-               .result = "\x74\x65\x73\x74\x20\x6d\x65\x2e",
-               .rlen   = 8,
-       }, {
-               .key    = "\x09\x65\x43\x11\x66\x44\x39\x25"
-                         "\x51\x3a\x16\x10\x0a\x08\x12\x6e",
-               .klen   = 16,
-               .input  = "\xbe\x7a\xbb\x81\x95\x2d\x1f\x1e"
-                         "\xdd\x89\xa1\x25\x04\x21\xdf\x95",
-               .ilen   = 16,
-               .result = "\x6c\x6f\x6e\x67\x65\x72\x5f\x74"
-                         "\x65\x73\x74\x5f\x76\x65\x63\x74",
-               .rlen   = 16,
-       }, {
-               .key    = "\x4d\x76\x32\x17\x05\x3f\x75\x2c"
-                         "\x5d\x04\x16\x36\x15\x72\x63\x2f",
-               .klen   = 16,
-               .input  = "\xe0\x4d\x5d\x3c\xb7\x8c\x36\x47"
-                         "\x94\x18\x95\x91\xa9\xfc\x49\xf8"
-                         "\x44\xd1\x2d\xc2\x99\xb8\x08\x2a"
-                         "\x07\x89\x73\xc2\x45\x92\xc6\x90",
-               .ilen   = 32,
-               .result = "\x54\x65\x61\x20\x69\x73\x20\x67"
-                         "\x6f\x6f\x64\x20\x66\x6f\x72\x20"
-                         "\x79\x6f\x75\x21\x21\x21\x20\x72"
-                         "\x65\x61\x6c\x6c\x79\x21\x21\x21",
-               .rlen   = 32,
-       }
-};
-
-/*
- * XTEA test vectors
- */
-#define XTEA_ENC_TEST_VECTORS  4
-#define XTEA_DEC_TEST_VECTORS  4
-
-static struct cipher_testvec xtea_enc_tv_template[] = {
-       {
-               .key    = zeroed_string,
-               .klen   = 16,
-               .input  = zeroed_string,
-               .ilen   = 8,
-               .result = "\xd8\xd4\xe9\xde\xd9\x1e\x13\xf7",
-               .rlen   = 8,
-       }, {
-               .key    = "\x2b\x02\x05\x68\x06\x14\x49\x76"
-                         "\x77\x5d\x0e\x26\x6c\x28\x78\x43",
-               .klen   = 16,
-               .input  = "\x74\x65\x73\x74\x20\x6d\x65\x2e",
-               .ilen   = 8,
-               .result = "\x94\xeb\xc8\x96\x84\x6a\x49\xa8",
-               .rlen   = 8,
-       }, {
-               .key    = "\x09\x65\x43\x11\x66\x44\x39\x25"
-                         "\x51\x3a\x16\x10\x0a\x08\x12\x6e",
-               .klen   = 16,
-               .input  = "\x6c\x6f\x6e\x67\x65\x72\x5f\x74"
-                         "\x65\x73\x74\x5f\x76\x65\x63\x74",
-               .ilen   = 16,
-               .result = "\x3e\xce\xae\x22\x60\x56\xa8\x9d"
-                         "\x77\x4d\xd4\xb4\x87\x24\xe3\x9a",
-               .rlen   = 16,
-       }, {
-               .key    = "\x4d\x76\x32\x17\x05\x3f\x75\x2c"
-                         "\x5d\x04\x16\x36\x15\x72\x63\x2f",
-               .klen   = 16,
-               .input  = "\x54\x65\x61\x20\x69\x73\x20\x67"
-                         "\x6f\x6f\x64\x20\x66\x6f\x72\x20"
-                         "\x79\x6f\x75\x21\x21\x21\x20\x72"
-                         "\x65\x61\x6c\x6c\x79\x21\x21\x21",
-               .ilen   = 32,
-               .result = "\x99\x81\x9f\x5d\x6f\x4b\x31\x3a"
-                         "\x86\xff\x6f\xd0\xe3\x87\x70\x07"
-                         "\x4d\xb8\xcf\xf3\x99\x50\xb3\xd4"
-                         "\x73\xa2\xfa\xc9\x16\x59\x5d\x81",
-               .rlen   = 32,
-       }
-};
-
-static struct cipher_testvec xtea_dec_tv_template[] = {
-       {
-               .key    = zeroed_string,
-               .klen   = 16,
-               .input  = "\xd8\xd4\xe9\xde\xd9\x1e\x13\xf7",
-               .ilen   = 8,
-               .result = zeroed_string,
-               .rlen   = 8,
-       }, {
-               .key    = "\x2b\x02\x05\x68\x06\x14\x49\x76"
-                         "\x77\x5d\x0e\x26\x6c\x28\x78\x43",
-               .klen   = 16,
-               .input  = "\x94\xeb\xc8\x96\x84\x6a\x49\xa8",
-               .ilen   = 8,
-               .result = "\x74\x65\x73\x74\x20\x6d\x65\x2e",
-               .rlen   = 8,
-       }, {
-               .key    = "\x09\x65\x43\x11\x66\x44\x39\x25"
-                         "\x51\x3a\x16\x10\x0a\x08\x12\x6e",
-               .klen   = 16,
-               .input  = "\x3e\xce\xae\x22\x60\x56\xa8\x9d"
-                         "\x77\x4d\xd4\xb4\x87\x24\xe3\x9a",
-               .ilen   = 16,
-               .result = "\x6c\x6f\x6e\x67\x65\x72\x5f\x74"
-                         "\x65\x73\x74\x5f\x76\x65\x63\x74",
-               .rlen   = 16,
-       }, {
-               .key    = "\x4d\x76\x32\x17\x05\x3f\x75\x2c"
-                         "\x5d\x04\x16\x36\x15\x72\x63\x2f",
-               .klen   = 16,
-               .input  = "\x99\x81\x9f\x5d\x6f\x4b\x31\x3a"
-                         "\x86\xff\x6f\xd0\xe3\x87\x70\x07"
-                         "\x4d\xb8\xcf\xf3\x99\x50\xb3\xd4"
-                         "\x73\xa2\xfa\xc9\x16\x59\x5d\x81",
-               .ilen   = 32,
-               .result = "\x54\x65\x61\x20\x69\x73\x20\x67"
-                         "\x6f\x6f\x64\x20\x66\x6f\x72\x20"
-                         "\x79\x6f\x75\x21\x21\x21\x20\x72"
-                         "\x65\x61\x6c\x6c\x79\x21\x21\x21",
-               .rlen   = 32,
-       }
-};
-
-/*
- * KHAZAD test vectors.
- */
-#define KHAZAD_ENC_TEST_VECTORS 5
-#define KHAZAD_DEC_TEST_VECTORS 5
-
-static struct cipher_testvec khazad_enc_tv_template[] = {
-       {
-               .key    = "\x80\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .klen   = 16,
-               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .ilen   = 8,
-               .result = "\x49\xa4\xce\x32\xac\x19\x0e\x3f",
-               .rlen   = 8,
-       }, {
-               .key    = "\x38\x38\x38\x38\x38\x38\x38\x38"
-                         "\x38\x38\x38\x38\x38\x38\x38\x38",
-               .klen   = 16,
-               .input  = "\x38\x38\x38\x38\x38\x38\x38\x38",
-               .ilen   = 8,
-               .result = "\x7e\x82\x12\xa1\xd9\x5b\xe4\xf9",
-               .rlen   = 8,
-       }, {
-               .key    = "\xa2\xa2\xa2\xa2\xa2\xa2\xa2\xa2"
-                       "\xa2\xa2\xa2\xa2\xa2\xa2\xa2\xa2",
-               .klen   = 16,
-               .input  = "\xa2\xa2\xa2\xa2\xa2\xa2\xa2\xa2",
-               .ilen   = 8,
-               .result = "\xaa\xbe\xc1\x95\xc5\x94\x1a\x9c",
-               .rlen   = 8,
-       }, {
-               .key    = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f"
-                       "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
-               .klen   = 16,
-               .input  = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
-               .ilen   = 8,
-               .result = "\x04\x74\xf5\x70\x50\x16\xd3\xb8",
-               .rlen   = 8,
-       }, {
-               .key    = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f"
-                       "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
-               .klen   = 16,
-               .input  = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f"
-                       "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
-               .ilen   = 16,
-               .result = "\x04\x74\xf5\x70\x50\x16\xd3\xb8"
-                       "\x04\x74\xf5\x70\x50\x16\xd3\xb8",
-               .rlen   = 16,
-       },
-};
-
-static struct cipher_testvec khazad_dec_tv_template[] = {
-       {
-               .key    = "\x80\x00\x00\x00\x00\x00\x00\x00"
-                         "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .klen   = 16,
-               .input  = "\x49\xa4\xce\x32\xac\x19\x0e\x3f",
-               .ilen   = 8,
-               .result = "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .rlen   = 8,
-       }, {
-               .key    = "\x38\x38\x38\x38\x38\x38\x38\x38"
-                         "\x38\x38\x38\x38\x38\x38\x38\x38",
-               .klen   = 16,
-               .input  = "\x7e\x82\x12\xa1\xd9\x5b\xe4\xf9",
-               .ilen   = 8,
-               .result = "\x38\x38\x38\x38\x38\x38\x38\x38",
-               .rlen   = 8,
-       }, {
-               .key    = "\xa2\xa2\xa2\xa2\xa2\xa2\xa2\xa2"
-                       "\xa2\xa2\xa2\xa2\xa2\xa2\xa2\xa2",
-               .klen   = 16,
-               .input  = "\xaa\xbe\xc1\x95\xc5\x94\x1a\x9c",
-               .ilen   = 8,
-               .result = "\xa2\xa2\xa2\xa2\xa2\xa2\xa2\xa2",
-               .rlen   = 8,
-       }, {
-               .key    = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f"
-                       "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
-               .klen   = 16,
-               .input  = "\x04\x74\xf5\x70\x50\x16\xd3\xb8",
-               .ilen   = 8,
-               .result = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
-               .rlen   = 8,
-       }, {
-               .key    = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f"
-                       "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
-               .klen   = 16,
-               .input  = "\x04\x74\xf5\x70\x50\x16\xd3\xb8"
-                       "\x04\x74\xf5\x70\x50\x16\xd3\xb8",
-               .ilen   = 16,
-               .result = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f"
-                       "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
-               .rlen   = 16,
-       },
-};
-
-/*
- * Anubis test vectors.
- */
-
-#define ANUBIS_ENC_TEST_VECTORS                        5
-#define ANUBIS_DEC_TEST_VECTORS                        5
-#define ANUBIS_CBC_ENC_TEST_VECTORS            2
-#define ANUBIS_CBC_DEC_TEST_VECTORS            2
-
-static struct cipher_testvec anubis_enc_tv_template[] = {
-       {
-               .key    = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
-                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
-               .klen   = 16,
-               .input  = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
-                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
-               .ilen   = 16,
-               .result = "\x6d\xc5\xda\xa2\x26\x7d\x62\x6f"
-                         "\x08\xb7\x52\x8e\x6e\x6e\x86\x90",
-               .rlen   = 16,
-       }, {
-
-               .key    = "\x03\x03\x03\x03\x03\x03\x03\x03"
-                         "\x03\x03\x03\x03\x03\x03\x03\x03"
-                         "\x03\x03\x03\x03",
-               .klen   = 20,
-               .input  = "\x03\x03\x03\x03\x03\x03\x03\x03"
-                         "\x03\x03\x03\x03\x03\x03\x03\x03",
-               .ilen   = 16,
-               .result = "\xdb\xf1\x42\xf4\xd1\x8a\xc7\x49"
-                         "\x87\x41\x6f\x82\x0a\x98\x64\xae",
-               .rlen   = 16,
-       }, {
-               .key    = "\x24\x24\x24\x24\x24\x24\x24\x24"
-                         "\x24\x24\x24\x24\x24\x24\x24\x24"
-                         "\x24\x24\x24\x24\x24\x24\x24\x24"
-                         "\x24\x24\x24\x24",
-               .klen   = 28,
-               .input  = "\x24\x24\x24\x24\x24\x24\x24\x24"
-                         "\x24\x24\x24\x24\x24\x24\x24\x24",
-               .ilen   = 16,
-               .result = "\xfd\x1b\x4a\xe3\xbf\xf0\xad\x3d"
-                         "\x06\xd3\x61\x27\xfd\x13\x9e\xde",
-               .rlen   = 16,
-       }, {
-               .key    = "\x25\x25\x25\x25\x25\x25\x25\x25"
-                         "\x25\x25\x25\x25\x25\x25\x25\x25"
-                         "\x25\x25\x25\x25\x25\x25\x25\x25"
-                         "\x25\x25\x25\x25\x25\x25\x25\x25",
-               .klen   = 32,
-               .input  = "\x25\x25\x25\x25\x25\x25\x25\x25"
-                         "\x25\x25\x25\x25\x25\x25\x25\x25",
-               .ilen   = 16,
-               .result = "\x1a\x91\xfb\x2b\xb7\x78\x6b\xc4"
-                       "\x17\xd9\xff\x40\x3b\x0e\xe5\xfe",
-               .rlen   = 16,
-       }, {
-               .key    = "\x35\x35\x35\x35\x35\x35\x35\x35"
-                         "\x35\x35\x35\x35\x35\x35\x35\x35"
-                         "\x35\x35\x35\x35\x35\x35\x35\x35"
-                         "\x35\x35\x35\x35\x35\x35\x35\x35"
-                         "\x35\x35\x35\x35\x35\x35\x35\x35",
-               .klen   = 40,
-               .input  = "\x35\x35\x35\x35\x35\x35\x35\x35"
-                         "\x35\x35\x35\x35\x35\x35\x35\x35",
-               .ilen   = 16,
-               .result = "\xa5\x2c\x85\x6f\x9c\xba\xa0\x97"
-                         "\x9e\xc6\x84\x0f\x17\x21\x07\xee",
-               .rlen   = 16,
-       },
-};
-
-static struct cipher_testvec anubis_dec_tv_template[] = {
-       {
-               .key    = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
-                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
-               .klen   = 16,
-               .input  = "\x6d\xc5\xda\xa2\x26\x7d\x62\x6f"
-                         "\x08\xb7\x52\x8e\x6e\x6e\x86\x90",
-               .ilen   = 16,
-               .result = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
-                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
-               .rlen   = 16,
-       }, {
-
-               .key    = "\x03\x03\x03\x03\x03\x03\x03\x03"
-                         "\x03\x03\x03\x03\x03\x03\x03\x03"
-                         "\x03\x03\x03\x03",
-               .klen   = 20,
-               .input  = "\xdb\xf1\x42\xf4\xd1\x8a\xc7\x49"
-                         "\x87\x41\x6f\x82\x0a\x98\x64\xae",
-               .ilen   = 16,
-               .result = "\x03\x03\x03\x03\x03\x03\x03\x03"
-                         "\x03\x03\x03\x03\x03\x03\x03\x03",
-               .rlen   = 16,
-       }, {
-               .key    = "\x24\x24\x24\x24\x24\x24\x24\x24"
-                         "\x24\x24\x24\x24\x24\x24\x24\x24"
-                         "\x24\x24\x24\x24\x24\x24\x24\x24"
-                         "\x24\x24\x24\x24",
-               .klen   = 28,
-               .input  = "\xfd\x1b\x4a\xe3\xbf\xf0\xad\x3d"
-                         "\x06\xd3\x61\x27\xfd\x13\x9e\xde",
-               .ilen   = 16,
-               .result = "\x24\x24\x24\x24\x24\x24\x24\x24"
-                         "\x24\x24\x24\x24\x24\x24\x24\x24",
-               .rlen   = 16,
-       }, {
-               .key    = "\x25\x25\x25\x25\x25\x25\x25\x25"
-                         "\x25\x25\x25\x25\x25\x25\x25\x25"
-                         "\x25\x25\x25\x25\x25\x25\x25\x25"
-                         "\x25\x25\x25\x25\x25\x25\x25\x25",
-               .klen   = 32,
-               .input  = "\x1a\x91\xfb\x2b\xb7\x78\x6b\xc4"
-                       "\x17\xd9\xff\x40\x3b\x0e\xe5\xfe",
-               .ilen   = 16,
-               .result = "\x25\x25\x25\x25\x25\x25\x25\x25"
-                         "\x25\x25\x25\x25\x25\x25\x25\x25",
-               .rlen   = 16,
-       }, {
-               .key    = "\x35\x35\x35\x35\x35\x35\x35\x35"
-                         "\x35\x35\x35\x35\x35\x35\x35\x35"
-                         "\x35\x35\x35\x35\x35\x35\x35\x35"
-                         "\x35\x35\x35\x35\x35\x35\x35\x35"
-                         "\x35\x35\x35\x35\x35\x35\x35\x35",
-               .input = "\xa5\x2c\x85\x6f\x9c\xba\xa0\x97"
-                        "\x9e\xc6\x84\x0f\x17\x21\x07\xee",
-               .klen   = 40,
-               .ilen   = 16,
-               .result = "\x35\x35\x35\x35\x35\x35\x35\x35"
-                         "\x35\x35\x35\x35\x35\x35\x35\x35",
-               .rlen   = 16,
-       },
-};
-
-static struct cipher_testvec anubis_cbc_enc_tv_template[] = {
-       {
-               .key    = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
-                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
-               .klen   = 16,
-               .input  = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
-                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
-                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
-                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
-               .ilen   = 32,
-               .result = "\x6d\xc5\xda\xa2\x26\x7d\x62\x6f"
-                         "\x08\xb7\x52\x8e\x6e\x6e\x86\x90"
-                         "\x86\xd8\xb5\x6f\x98\x5e\x8a\x66"
-                         "\x4f\x1f\x78\xa1\xbb\x37\xf1\xbe",
-               .rlen   = 32,
-       }, {
-               .key    = "\x35\x35\x35\x35\x35\x35\x35\x35"
-                         "\x35\x35\x35\x35\x35\x35\x35\x35"
-                         "\x35\x35\x35\x35\x35\x35\x35\x35"
-                         "\x35\x35\x35\x35\x35\x35\x35\x35"
-                         "\x35\x35\x35\x35\x35\x35\x35\x35",
-               .klen   = 40,
-               .input  = "\x35\x35\x35\x35\x35\x35\x35\x35"
-                         "\x35\x35\x35\x35\x35\x35\x35\x35"
-                         "\x35\x35\x35\x35\x35\x35\x35\x35"
-                         "\x35\x35\x35\x35\x35\x35\x35\x35",
-               .ilen   = 32,
-               .result = "\xa5\x2c\x85\x6f\x9c\xba\xa0\x97"
-                         "\x9e\xc6\x84\x0f\x17\x21\x07\xee"
-                         "\xa2\xbc\x06\x98\xc6\x4b\xda\x75"
-                         "\x2e\xaa\xbe\x58\xce\x01\x5b\xc7",
-               .rlen   = 32,
-       },
-};
-
-static struct cipher_testvec anubis_cbc_dec_tv_template[] = {
-       {
-               .key    = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
-                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
-               .klen   = 16,
-               .input  = "\x6d\xc5\xda\xa2\x26\x7d\x62\x6f"
-                         "\x08\xb7\x52\x8e\x6e\x6e\x86\x90"
-                         "\x86\xd8\xb5\x6f\x98\x5e\x8a\x66"
-                         "\x4f\x1f\x78\xa1\xbb\x37\xf1\xbe",
-               .ilen   = 32,
-               .result = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
-                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
-                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
-                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
-               .rlen   = 32,
-       }, {
-               .key    = "\x35\x35\x35\x35\x35\x35\x35\x35"
-                         "\x35\x35\x35\x35\x35\x35\x35\x35"
-                         "\x35\x35\x35\x35\x35\x35\x35\x35"
-                         "\x35\x35\x35\x35\x35\x35\x35\x35"
-                         "\x35\x35\x35\x35\x35\x35\x35\x35",
-               .klen   = 40,
-               .input = "\xa5\x2c\x85\x6f\x9c\xba\xa0\x97"
-                         "\x9e\xc6\x84\x0f\x17\x21\x07\xee"
-                         "\xa2\xbc\x06\x98\xc6\x4b\xda\x75"
-                         "\x2e\xaa\xbe\x58\xce\x01\x5b\xc7",
-               .ilen   = 32,
-               .result = "\x35\x35\x35\x35\x35\x35\x35\x35"
-                         "\x35\x35\x35\x35\x35\x35\x35\x35"
-                         "\x35\x35\x35\x35\x35\x35\x35\x35"
-                         "\x35\x35\x35\x35\x35\x35\x35\x35",
-               .rlen   = 32,
-       },
-};
-
-/* 
- * XETA test vectors 
- */
-#define XETA_ENC_TEST_VECTORS  4
-#define XETA_DEC_TEST_VECTORS  4
-
-static struct cipher_testvec xeta_enc_tv_template[] = {
-       {
-               .key    = zeroed_string,
-               .klen   = 16,
-               .input  = zeroed_string,
-               .ilen   = 8,
-               .result = "\xaa\x22\x96\xe5\x6c\x61\xf3\x45",
-               .rlen   = 8,
-       }, {
-               .key    = "\x2b\x02\x05\x68\x06\x14\x49\x76"
-                         "\x77\x5d\x0e\x26\x6c\x28\x78\x43",
-               .klen   = 16,
-               .input  = "\x74\x65\x73\x74\x20\x6d\x65\x2e",
-               .ilen   = 8,
-               .result = "\x82\x3e\xeb\x35\xdc\xdd\xd9\xc3",
-               .rlen   = 8,
-       }, {
-               .key    = "\x09\x65\x43\x11\x66\x44\x39\x25"
-                         "\x51\x3a\x16\x10\x0a\x08\x12\x6e",
-               .klen   = 16,
-               .input  = "\x6c\x6f\x6e\x67\x65\x72\x5f\x74"
-                         "\x65\x73\x74\x5f\x76\x65\x63\x74",
-               .ilen   = 16,
-               .result = "\xe2\x04\xdb\xf2\x89\x85\x9e\xea"
-                         "\x61\x35\xaa\xed\xb5\xcb\x71\x2c",
-               .rlen   = 16,
-       }, {
-               .key    = "\x4d\x76\x32\x17\x05\x3f\x75\x2c"
-                         "\x5d\x04\x16\x36\x15\x72\x63\x2f",
-               .klen   = 16,
-               .input  = "\x54\x65\x61\x20\x69\x73\x20\x67"
-                         "\x6f\x6f\x64\x20\x66\x6f\x72\x20"
-                         "\x79\x6f\x75\x21\x21\x21\x20\x72"
-                         "\x65\x61\x6c\x6c\x79\x21\x21\x21",
-               .ilen   = 32,
-               .result = "\x0b\x03\xcd\x8a\xbe\x95\xfd\xb1"
-                         "\xc1\x44\x91\x0b\xa5\xc9\x1b\xb4"
-                         "\xa9\xda\x1e\x9e\xb1\x3e\x2a\x8f"
-                         "\xea\xa5\x6a\x85\xd1\xf4\xa8\xa5",
-               .rlen   = 32,
-       }
-};
-
-static struct cipher_testvec xeta_dec_tv_template[] = {
-       {
-               .key    = zeroed_string,
-               .klen   = 16,
-               .input  = "\xaa\x22\x96\xe5\x6c\x61\xf3\x45",
-               .ilen   = 8,
-               .result = zeroed_string,
-               .rlen   = 8,
-       }, {
-               .key    = "\x2b\x02\x05\x68\x06\x14\x49\x76"
-                         "\x77\x5d\x0e\x26\x6c\x28\x78\x43",
-               .klen   = 16,
-               .input  = "\x82\x3e\xeb\x35\xdc\xdd\xd9\xc3",
-               .ilen   = 8,
-               .result = "\x74\x65\x73\x74\x20\x6d\x65\x2e",
-               .rlen   = 8,
-       }, {
-               .key    = "\x09\x65\x43\x11\x66\x44\x39\x25"
-                         "\x51\x3a\x16\x10\x0a\x08\x12\x6e",
-               .klen   = 16,
-               .input  = "\xe2\x04\xdb\xf2\x89\x85\x9e\xea"
-                         "\x61\x35\xaa\xed\xb5\xcb\x71\x2c",
-               .ilen   = 16,
-               .result = "\x6c\x6f\x6e\x67\x65\x72\x5f\x74"
-                         "\x65\x73\x74\x5f\x76\x65\x63\x74",
-               .rlen   = 16,
-       }, {
-               .key    = "\x4d\x76\x32\x17\x05\x3f\x75\x2c"
-                         "\x5d\x04\x16\x36\x15\x72\x63\x2f",
-               .klen   = 16,
-               .input  = "\x0b\x03\xcd\x8a\xbe\x95\xfd\xb1"
-                         "\xc1\x44\x91\x0b\xa5\xc9\x1b\xb4"
-                         "\xa9\xda\x1e\x9e\xb1\x3e\x2a\x8f"
-                         "\xea\xa5\x6a\x85\xd1\xf4\xa8\xa5",
-               .ilen   = 32,
-               .result = "\x54\x65\x61\x20\x69\x73\x20\x67"
-                         "\x6f\x6f\x64\x20\x66\x6f\x72\x20"
-                         "\x79\x6f\x75\x21\x21\x21\x20\x72"
-                         "\x65\x61\x6c\x6c\x79\x21\x21\x21",
-               .rlen   = 32,
-       }
-};
-
-/* 
- * FCrypt test vectors 
- */
-#define FCRYPT_ENC_TEST_VECTORS        ARRAY_SIZE(fcrypt_pcbc_enc_tv_template)
-#define FCRYPT_DEC_TEST_VECTORS        ARRAY_SIZE(fcrypt_pcbc_dec_tv_template)
-
-static struct cipher_testvec fcrypt_pcbc_enc_tv_template[] = {
-       { /* http://www.openafs.org/pipermail/openafs-devel/2000-December/005320.html */
-               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .klen   = 8,
-               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .ilen   = 8,
-               .result = "\x0E\x09\x00\xC7\x3E\xF7\xED\x41",
-               .rlen   = 8,
-       }, {
-               .key    = "\x11\x44\x77\xAA\xDD\x00\x33\x66",
-               .klen   = 8,
-               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .input  = "\x12\x34\x56\x78\x9A\xBC\xDE\xF0",
-               .ilen   = 8,
-               .result = "\xD8\xED\x78\x74\x77\xEC\x06\x80",
-               .rlen   = 8,
-       }, { /* From Arla */
-               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
-               .klen   = 8,
-               .iv     = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
-               .input  = "The quick brown fox jumps over the lazy dogs.\0\0",
-               .ilen   = 48,
-               .result = "\x00\xf0\x0e\x11\x75\xe6\x23\x82"
-                         "\xee\xac\x98\x62\x44\x51\xe4\x84"
-                         "\xc3\x59\xd8\xaa\x64\x60\xae\xf7"
-                         "\xd2\xd9\x13\x79\x72\xa3\x45\x03"
-                         "\x23\xb5\x62\xd7\x0c\xf5\x27\xd1"
-                         "\xf8\x91\x3c\xac\x44\x22\x92\xef",
-               .rlen   = 48,
-       }, {
-               .key    = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
-               .klen   = 8,
-               .iv     = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
-               .input  = "The quick brown fox jumps over the lazy dogs.\0\0",
-               .ilen   = 48,
-               .result = "\xca\x90\xf5\x9d\xcb\xd4\xd2\x3c"
-                         "\x01\x88\x7f\x3e\x31\x6e\x62\x9d"
-                         "\xd8\xe0\x57\xa3\x06\x3a\x42\x58"
-                         "\x2a\x28\xfe\x72\x52\x2f\xdd\xe0"
-                         "\x19\x89\x09\x1c\x2a\x8e\x8c\x94"
-                         "\xfc\xc7\x68\xe4\x88\xaa\xde\x0f",
-               .rlen   = 48,
-       }, { /* split-page version */
-               .key    = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
-               .klen   = 8,
-               .iv     = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
-               .input  = "The quick brown fox jumps over the lazy dogs.\0\0",
-               .ilen   = 48,
-               .result = "\xca\x90\xf5\x9d\xcb\xd4\xd2\x3c"
-                         "\x01\x88\x7f\x3e\x31\x6e\x62\x9d"
-                         "\xd8\xe0\x57\xa3\x06\x3a\x42\x58"
-                         "\x2a\x28\xfe\x72\x52\x2f\xdd\xe0"
-                         "\x19\x89\x09\x1c\x2a\x8e\x8c\x94"
-                         "\xfc\xc7\x68\xe4\x88\xaa\xde\x0f",
-               .rlen   = 48,
-               .np     = 2,
-               .tap    = { 20, 28 },
-       }
-};
-
-static struct cipher_testvec fcrypt_pcbc_dec_tv_template[] = {
-       { /* http://www.openafs.org/pipermail/openafs-devel/2000-December/005320.html */
-               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .klen   = 8,
-               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .input  = "\x0E\x09\x00\xC7\x3E\xF7\xED\x41",
-               .ilen   = 8,
-               .result = "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .rlen   = 8,
-       }, {
-               .key    = "\x11\x44\x77\xAA\xDD\x00\x33\x66",
-               .klen   = 8,
-               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .input  = "\xD8\xED\x78\x74\x77\xEC\x06\x80",
-               .ilen   = 8,
-               .result = "\x12\x34\x56\x78\x9A\xBC\xDE\xF0",
-               .rlen   = 8,
-       }, { /* From Arla */
-               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
-               .klen   = 8,
-               .iv     = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
-               .input  = "\x00\xf0\x0e\x11\x75\xe6\x23\x82"
-                         "\xee\xac\x98\x62\x44\x51\xe4\x84"
-                         "\xc3\x59\xd8\xaa\x64\x60\xae\xf7"
-                         "\xd2\xd9\x13\x79\x72\xa3\x45\x03"
-                         "\x23\xb5\x62\xd7\x0c\xf5\x27\xd1"
-                         "\xf8\x91\x3c\xac\x44\x22\x92\xef",
-               .ilen   = 48,
-               .result = "The quick brown fox jumps over the lazy dogs.\0\0",
-               .rlen   = 48,
-       }, {
-               .key    = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
-               .klen   = 8,
-               .iv     = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
-               .input  = "\xca\x90\xf5\x9d\xcb\xd4\xd2\x3c"
-                         "\x01\x88\x7f\x3e\x31\x6e\x62\x9d"
-                         "\xd8\xe0\x57\xa3\x06\x3a\x42\x58"
-                         "\x2a\x28\xfe\x72\x52\x2f\xdd\xe0"
-                         "\x19\x89\x09\x1c\x2a\x8e\x8c\x94"
-                         "\xfc\xc7\x68\xe4\x88\xaa\xde\x0f",
-               .ilen   = 48,
-               .result = "The quick brown fox jumps over the lazy dogs.\0\0",
-               .rlen   = 48,
-       }, { /* split-page version */
-               .key    = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
-               .klen   = 8,
-               .iv     = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
-               .input  = "\xca\x90\xf5\x9d\xcb\xd4\xd2\x3c"
-                         "\x01\x88\x7f\x3e\x31\x6e\x62\x9d"
-                         "\xd8\xe0\x57\xa3\x06\x3a\x42\x58"
-                         "\x2a\x28\xfe\x72\x52\x2f\xdd\xe0"
-                         "\x19\x89\x09\x1c\x2a\x8e\x8c\x94"
-                         "\xfc\xc7\x68\xe4\x88\xaa\xde\x0f",
-               .ilen   = 48,
-               .result = "The quick brown fox jumps over the lazy dogs.\0\0",
-               .rlen   = 48,
-               .np     = 2,
-               .tap    = { 20, 28 },
-       }
-};
-
-/*
- * CAMELLIA test vectors.
- */
-#define CAMELLIA_ENC_TEST_VECTORS 3
-#define CAMELLIA_DEC_TEST_VECTORS 3
-#define CAMELLIA_CBC_ENC_TEST_VECTORS 2
-#define CAMELLIA_CBC_DEC_TEST_VECTORS 2
-
-static struct cipher_testvec camellia_enc_tv_template[] = {
-       {
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
-                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
-               .klen   = 16,
-               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xef"
-                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
-               .ilen   = 16,
-               .result = "\x67\x67\x31\x38\x54\x96\x69\x73"
-                         "\x08\x57\x06\x56\x48\xea\xbe\x43",
-               .rlen   = 16,
-       }, {
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
-                         "\xfe\xdc\xba\x98\x76\x54\x32\x10"
-                         "\x00\x11\x22\x33\x44\x55\x66\x77",
-               .klen   = 24,
-               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xef"
-                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
-               .ilen   = 16,
-               .result = "\xb4\x99\x34\x01\xb3\xe9\x96\xf8"
-                         "\x4e\xe5\xce\xe7\xd7\x9b\x09\xb9",
-               .rlen   = 16,
-       }, {
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
-                         "\xfe\xdc\xba\x98\x76\x54\x32\x10"
-                         "\x00\x11\x22\x33\x44\x55\x66\x77"
-                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
-               .klen   = 32,
-               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xef"
-                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
-               .ilen   = 16,
-               .result = "\x9a\xcc\x23\x7d\xff\x16\xd7\x6c"
-                         "\x20\xef\x7c\x91\x9e\x3a\x75\x09",
-               .rlen   = 16,
-       },
-};
-
-static struct cipher_testvec camellia_dec_tv_template[] = {
-       {
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
-                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
-               .klen   = 16,
-               .input  = "\x67\x67\x31\x38\x54\x96\x69\x73"
-                         "\x08\x57\x06\x56\x48\xea\xbe\x43",
-               .ilen   = 16,
-               .result = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\x55\x55\x55\x55\x55\x55\x55\x55"
                          "\xfe\xdc\xba\x98\x76\x54\x32\x10",
-               .rlen   = 16,
-       }, {
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
-                         "\xfe\xdc\xba\x98\x76\x54\x32\x10"
-                         "\x00\x11\x22\x33\x44\x55\x66\x77",
                .klen   = 24,
-               .input  = "\xb4\x99\x34\x01\xb3\xe9\x96\xf8"
-                         "\x4e\xe5\xce\xe7\xd7\x9b\x09\xb9",
-               .ilen   = 16,
-               .result = "\x01\x23\x45\x67\x89\xab\xcd\xef"
-                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
-               .rlen   = 16,
-       }, {
-               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
-                         "\xfe\xdc\xba\x98\x76\x54\x32\x10"
-                         "\x00\x11\x22\x33\x44\x55\x66\x77"
-                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
-               .klen   = 32,
-               .input  = "\x9a\xcc\x23\x7d\xff\x16\xd7\x6c"
-                         "\x20\xef\x7c\x91\x9e\x3a\x75\x09",
-               .ilen   = 16,
-               .result = "\x01\x23\x45\x67\x89\xab\xcd\xef"
-                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
-               .rlen   = 16,
-       },
-};
-
-static struct cipher_testvec camellia_cbc_enc_tv_template[] = {
-       {
-               .key    = "\x06\xa9\x21\x40\x36\xb8\xa1\x5b"
-                         "\x51\x2e\x03\xd5\x34\x12\x00\x06",
-               .klen   = 16,
-               .iv     = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30"
-                         "\xb4\x22\xda\x80\x2c\x9f\xac\x41",
-               .input  = "Single block msg",
-               .ilen   = 16,
-               .result = "\xea\x32\x12\x76\x3b\x50\x10\xe7"
-                         "\x18\xf6\xfd\x5d\xf6\x8f\x13\x51",
-               .rlen   = 16,
-       }, {
-               .key    = "\xc2\x86\x69\x6d\x88\x7c\x9a\xa0"
-                         "\x61\x1b\xbb\x3e\x20\x25\xa4\x5a",
-               .klen   = 16,
-               .iv     = "\x56\x2e\x17\x99\x6d\x09\x3d\x28"
-                         "\xdd\xb3\xba\x69\x5a\x2e\x6f\x58",
-               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                         "\x10\x11\x12\x13\x14\x15\x16\x17"
-                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
-               .ilen   = 32,
-               .result = "\xa5\xdf\x6e\x50\xda\x70\x6c\x01"
-                         "\x4a\xab\xf3\xf2\xd6\xfc\x6c\xfd"
-                         "\x19\xb4\x3e\x57\x1c\x02\x5e\xa0"
-                         "\x15\x78\xe0\x5e\xf2\xcb\x87\x16",
-               .rlen   = 32,
-       },
-};
-
-static struct cipher_testvec camellia_cbc_dec_tv_template[] = {
-       {
-               .key    = "\x06\xa9\x21\x40\x36\xb8\xa1\x5b"
-                         "\x51\x2e\x03\xd5\x34\x12\x00\x06",
-               .klen   = 16,
-               .iv     = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30"
-                         "\xb4\x22\xda\x80\x2c\x9f\xac\x41",
-               .input  = "\xea\x32\x12\x76\x3b\x50\x10\xe7"
-                         "\x18\xf6\xfd\x5d\xf6\x8f\x13\x51",
-               .ilen   = 16,
-               .result = "Single block msg",
-               .rlen   = 16,
-       }, {
-               .key    = "\xc2\x86\x69\x6d\x88\x7c\x9a\xa0"
-                         "\x61\x1b\xbb\x3e\x20\x25\xa4\x5a",
-               .klen   = 16,
-               .iv     = "\x56\x2e\x17\x99\x6d\x09\x3d\x28"
-                         "\xdd\xb3\xba\x69\x5a\x2e\x6f\x58",
-               .input = "\xa5\xdf\x6e\x50\xda\x70\x6c\x01"
-                         "\x4a\xab\xf3\xf2\xd6\xfc\x6c\xfd"
-                         "\x19\xb4\x3e\x57\x1c\x02\x5e\xa0"
-                         "\x15\x78\xe0\x5e\xf2\xcb\x87\x16",
-               .ilen   = 32,
-               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                         "\x10\x11\x12\x13\x14\x15\x16\x17"
-                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
-               .rlen   = 32,
-       },
-};
-
-/*
- * SEED test vectors
- */
-#define SEED_ENC_TEST_VECTORS  4
-#define SEED_DEC_TEST_VECTORS  4
-
-static struct cipher_testvec seed_enc_tv_template[] = {
-       {
-               .key    = zeroed_string,
-               .klen   = 16,
-               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-               .ilen   = 16,
-               .result = "\x5e\xba\xc6\xe0\x05\x4e\x16\x68"
-                         "\x19\xaf\xf1\xcc\x6d\x34\x6c\xdb",
-               .rlen   = 16,
-       }, {
-               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-               .klen   = 16,
-               .input  = zeroed_string,
-               .ilen   = 16,
-               .result = "\xc1\x1f\x22\xf2\x01\x40\x50\x50"
-                         "\x84\x48\x35\x97\xe4\x37\x0f\x43",
-               .rlen   = 16,
-       }, {
-               .key    = "\x47\x06\x48\x08\x51\xe6\x1b\xe8"
-                         "\x5d\x74\xbf\xb3\xfd\x95\x61\x85",
-               .klen   = 16,
-               .input  = "\x83\xa2\xf8\xa2\x88\x64\x1f\xb9"
-                         "\xa4\xe9\xa5\xcc\x2f\x13\x1c\x7d",
-               .ilen   = 16,
-               .result = "\xee\x54\xd1\x3e\xbc\xae\x70\x6d"
-                         "\x22\x6b\xc3\x14\x2c\xd4\x0d\x4a",
-               .rlen   = 16,
-       }, {
-               .key    = "\x28\xdb\xc3\xbc\x49\xff\xd8\x7d"
-                         "\xcf\xa5\x09\xb1\x1d\x42\x2b\xe7",
-               .klen   = 16,
-               .input  = "\xb4\x1e\x6b\xe2\xeb\xa8\x4a\x14"
-                         "\x8e\x2e\xed\x84\x59\x3c\x5e\xc7",
-               .ilen   = 16,
-               .result = "\x9b\x9b\x7b\xfc\xd1\x81\x3c\xb9"
-                         "\x5d\x0b\x36\x18\xf4\x0f\x51\x22",
-               .rlen   = 16,
        }
 };
 
-static struct cipher_testvec seed_dec_tv_template[] = {
-       {
-               .key    = zeroed_string,
-               .klen   = 16,
-               .input  = "\x5e\xba\xc6\xe0\x05\x4e\x16\x68"
-                         "\x19\xaf\xf1\xcc\x6d\x34\x6c\xdb",
-               .ilen   = 16,
-               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-               .rlen   = 16,
-       }, {
-               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
-               .klen   = 16,
-               .input  = "\xc1\x1f\x22\xf2\x01\x40\x50\x50"
-                         "\x84\x48\x35\x97\xe4\x37\x0f\x43",
-               .ilen   = 16,
-               .result = zeroed_string,
-               .rlen   = 16,
-       }, {
-               .key    = "\x47\x06\x48\x08\x51\xe6\x1b\xe8"
-                         "\x5d\x74\xbf\xb3\xfd\x95\x61\x85",
-               .klen   = 16,
-               .input  = "\xee\x54\xd1\x3e\xbc\xae\x70\x6d"
-                         "\x22\x6b\xc3\x14\x2c\xd4\x0d\x4a",
-               .ilen   = 16,
-               .result = "\x83\xa2\xf8\xa2\x88\x64\x1f\xb9"
-                         "\xa4\xe9\xa5\xcc\x2f\x13\x1c\x7d",
-               .rlen   = 16,
-       }, {
-               .key    = "\x28\xdb\xc3\xbc\x49\xff\xd8\x7d"
-                         "\xcf\xa5\x09\xb1\x1d\x42\x2b\xe7",
-               .klen   = 16,
-               .input  = "\x9b\x9b\x7b\xfc\xd1\x81\x3c\xb9"
-                         "\x5d\x0b\x36\x18\xf4\x0f\x51\x22",
-               .ilen   = 16,
-               .result = "\xb4\x1e\x6b\xe2\xeb\xa8\x4a\x14"
-                         "\x8e\x2e\xed\x84\x59\x3c\x5e\xc7",
-               .rlen   = 16,
-       }
-};
-
-#define SALSA20_STREAM_ENC_TEST_VECTORS 5
-static struct cipher_testvec salsa20_stream_enc_tv_template[] = {
-       /*
-       * Testvectors from verified.test-vectors submitted to ECRYPT.
-       * They are truncated to size 39, 64, 111, 129 to test a variety
-       * of input length.
-       */
-       { /* Set 3, vector 0 */
-               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
-                       "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F",
-               .klen   = 16,
-               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00",
-               .ilen   = 39,
-               .result = "\x2D\xD5\xC3\xF7\xBA\x2B\x20\xF7"
-                        "\x68\x02\x41\x0C\x68\x86\x88\x89"
-                        "\x5A\xD8\xC1\xBD\x4E\xA6\xC9\xB1"
-                        "\x40\xFB\x9B\x90\xE2\x10\x49\xBF"
-                        "\x58\x3F\x52\x79\x70\xEB\xC1",
-               .rlen   = 39,
-       }, { /* Set 5, vector 0 */
-               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .klen   = 16,
-               .iv     = "\x80\x00\x00\x00\x00\x00\x00\x00",
-               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .ilen   = 64,
-               .result = "\xB6\x6C\x1E\x44\x46\xDD\x95\x57"
-                        "\xE5\x78\xE2\x23\xB0\xB7\x68\x01"
-                        "\x7B\x23\xB2\x67\xBB\x02\x34\xAE"
-                        "\x46\x26\xBF\x44\x3F\x21\x97\x76"
-                        "\x43\x6F\xB1\x9F\xD0\xE8\x86\x6F"
-                        "\xCD\x0D\xE9\xA9\x53\x8F\x4A\x09"
-                        "\xCA\x9A\xC0\x73\x2E\x30\xBC\xF9"
-                        "\x8E\x4F\x13\xE4\xB9\xE2\x01\xD9",
-               .rlen   = 64,
-       }, { /* Set 3, vector 27 */
-               .key    = "\x1B\x1C\x1D\x1E\x1F\x20\x21\x22"
-                       "\x23\x24\x25\x26\x27\x28\x29\x2A"
-                       "\x2B\x2C\x2D\x2E\x2F\x30\x31\x32"
-                       "\x33\x34\x35\x36\x37\x38\x39\x3A",
-               .klen   = 32,
-               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00",
-               .ilen   = 111,
-               .result = "\xAE\x39\x50\x8E\xAC\x9A\xEC\xE7"
-                        "\xBF\x97\xBB\x20\xB9\xDE\xE4\x1F"
-                        "\x87\xD9\x47\xF8\x28\x91\x35\x98"
-                        "\xDB\x72\xCC\x23\x29\x48\x56\x5E"
-                        "\x83\x7E\x0B\xF3\x7D\x5D\x38\x7B"
-                        "\x2D\x71\x02\xB4\x3B\xB5\xD8\x23"
-                        "\xB0\x4A\xDF\x3C\xEC\xB6\xD9\x3B"
-                        "\x9B\xA7\x52\xBE\xC5\xD4\x50\x59"
-                        "\x15\x14\xB4\x0E\x40\xE6\x53\xD1"
-                        "\x83\x9C\x5B\xA0\x92\x29\x6B\x5E"
-                        "\x96\x5B\x1E\x2F\xD3\xAC\xC1\x92"
-                        "\xB1\x41\x3F\x19\x2F\xC4\x3B\xC6"
-                        "\x95\x46\x45\x54\xE9\x75\x03\x08"
-                        "\x44\xAF\xE5\x8A\x81\x12\x09",
-               .rlen   = 111,
-       }, { /* Set 5, vector 27 */
-               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .klen   = 32,
-               .iv     = "\x00\x00\x00\x10\x00\x00\x00\x00",
-               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00",
-               .ilen   = 129,
-               .result = "\xD2\xDB\x1A\x5C\xF1\xC1\xAC\xDB"
-                        "\xE8\x1A\x7A\x43\x40\xEF\x53\x43"
-                        "\x5E\x7F\x4B\x1A\x50\x52\x3F\x8D"
-                        "\x28\x3D\xCF\x85\x1D\x69\x6E\x60"
-                        "\xF2\xDE\x74\x56\x18\x1B\x84\x10"
-                        "\xD4\x62\xBA\x60\x50\xF0\x61\xF2"
-                        "\x1C\x78\x7F\xC1\x24\x34\xAF\x58"
-                        "\xBF\x2C\x59\xCA\x90\x77\xF3\xB0"
-                        "\x5B\x4A\xDF\x89\xCE\x2C\x2F\xFC"
-                        "\x67\xF0\xE3\x45\xE8\xB3\xB3\x75"
-                        "\xA0\x95\x71\xA1\x29\x39\x94\xCA"
-                        "\x45\x2F\xBD\xCB\x10\xB6\xBE\x9F"
-                        "\x8E\xF9\xB2\x01\x0A\x5A\x0A\xB7"
-                        "\x6B\x9D\x70\x8E\x4B\xD6\x2F\xCD"
-                        "\x2E\x40\x48\x75\xE9\xE2\x21\x45"
-                        "\x0B\xC9\xB6\xB5\x66\xBC\x9A\x59"
-                        "\x5A",
-               .rlen   = 129,
-       }, { /* large test vector generated using Crypto++ */
-               .key =  "\x00\x01\x02\x03\x04\x05\x06\x07"
-                       "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                       "\x10\x11\x12\x13\x14\x15\x16\x17"
-                       "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
-               .klen = 32,
-               .iv =   "\x00\x00\x00\x00\x00\x00\x00\x00"
-                       "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .input =
-                       "\x00\x01\x02\x03\x04\x05\x06\x07"
-                       "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
-                       "\x10\x11\x12\x13\x14\x15\x16\x17"
-                       "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
-                       "\x20\x21\x22\x23\x24\x25\x26\x27"
-                       "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
-                       "\x30\x31\x32\x33\x34\x35\x36\x37"
-                       "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
-                       "\x40\x41\x42\x43\x44\x45\x46\x47"
-                       "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
-                       "\x50\x51\x52\x53\x54\x55\x56\x57"
-                       "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
-                       "\x60\x61\x62\x63\x64\x65\x66\x67"
-                       "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
-                       "\x70\x71\x72\x73\x74\x75\x76\x77"
-                       "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
-                       "\x80\x81\x82\x83\x84\x85\x86\x87"
-                       "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
-                       "\x90\x91\x92\x93\x94\x95\x96\x97"
-                       "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
-                       "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
-                       "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
-                       "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
-                       "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
-                       "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
-                       "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
-                       "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
-                       "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
-                       "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
-                       "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
-                       "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
-                       "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
-                       "\x00\x03\x06\x09\x0c\x0f\x12\x15"
-                       "\x18\x1b\x1e\x21\x24\x27\x2a\x2d"
-                       "\x30\x33\x36\x39\x3c\x3f\x42\x45"
-                       "\x48\x4b\x4e\x51\x54\x57\x5a\x5d"
-                       "\x60\x63\x66\x69\x6c\x6f\x72\x75"
-                       "\x78\x7b\x7e\x81\x84\x87\x8a\x8d"
-                       "\x90\x93\x96\x99\x9c\x9f\xa2\xa5"
-                       "\xa8\xab\xae\xb1\xb4\xb7\xba\xbd"
-                       "\xc0\xc3\xc6\xc9\xcc\xcf\xd2\xd5"
-                       "\xd8\xdb\xde\xe1\xe4\xe7\xea\xed"
-                       "\xf0\xf3\xf6\xf9\xfc\xff\x02\x05"
-                       "\x08\x0b\x0e\x11\x14\x17\x1a\x1d"
-                       "\x20\x23\x26\x29\x2c\x2f\x32\x35"
-                       "\x38\x3b\x3e\x41\x44\x47\x4a\x4d"
-                       "\x50\x53\x56\x59\x5c\x5f\x62\x65"
-                       "\x68\x6b\x6e\x71\x74\x77\x7a\x7d"
-                       "\x80\x83\x86\x89\x8c\x8f\x92\x95"
-                       "\x98\x9b\x9e\xa1\xa4\xa7\xaa\xad"
-                       "\xb0\xb3\xb6\xb9\xbc\xbf\xc2\xc5"
-                       "\xc8\xcb\xce\xd1\xd4\xd7\xda\xdd"
-                       "\xe0\xe3\xe6\xe9\xec\xef\xf2\xf5"
-                       "\xf8\xfb\xfe\x01\x04\x07\x0a\x0d"
-                       "\x10\x13\x16\x19\x1c\x1f\x22\x25"
-                       "\x28\x2b\x2e\x31\x34\x37\x3a\x3d"
-                       "\x40\x43\x46\x49\x4c\x4f\x52\x55"
-                       "\x58\x5b\x5e\x61\x64\x67\x6a\x6d"
-                       "\x70\x73\x76\x79\x7c\x7f\x82\x85"
-                       "\x88\x8b\x8e\x91\x94\x97\x9a\x9d"
-                       "\xa0\xa3\xa6\xa9\xac\xaf\xb2\xb5"
-                       "\xb8\xbb\xbe\xc1\xc4\xc7\xca\xcd"
-                       "\xd0\xd3\xd6\xd9\xdc\xdf\xe2\xe5"
-                       "\xe8\xeb\xee\xf1\xf4\xf7\xfa\xfd"
-                       "\x00\x05\x0a\x0f\x14\x19\x1e\x23"
-                       "\x28\x2d\x32\x37\x3c\x41\x46\x4b"
-                       "\x50\x55\x5a\x5f\x64\x69\x6e\x73"
-                       "\x78\x7d\x82\x87\x8c\x91\x96\x9b"
-                       "\xa0\xa5\xaa\xaf\xb4\xb9\xbe\xc3"
-                       "\xc8\xcd\xd2\xd7\xdc\xe1\xe6\xeb"
-                       "\xf0\xf5\xfa\xff\x04\x09\x0e\x13"
-                       "\x18\x1d\x22\x27\x2c\x31\x36\x3b"
-                       "\x40\x45\x4a\x4f\x54\x59\x5e\x63"
-                       "\x68\x6d\x72\x77\x7c\x81\x86\x8b"
-                       "\x90\x95\x9a\x9f\xa4\xa9\xae\xb3"
-                       "\xb8\xbd\xc2\xc7\xcc\xd1\xd6\xdb"
-                       "\xe0\xe5\xea\xef\xf4\xf9\xfe\x03"
-                       "\x08\x0d\x12\x17\x1c\x21\x26\x2b"
-                       "\x30\x35\x3a\x3f\x44\x49\x4e\x53"
-                       "\x58\x5d\x62\x67\x6c\x71\x76\x7b"
-                       "\x80\x85\x8a\x8f\x94\x99\x9e\xa3"
-                       "\xa8\xad\xb2\xb7\xbc\xc1\xc6\xcb"
-                       "\xd0\xd5\xda\xdf\xe4\xe9\xee\xf3"
-                       "\xf8\xfd\x02\x07\x0c\x11\x16\x1b"
-                       "\x20\x25\x2a\x2f\x34\x39\x3e\x43"
-                       "\x48\x4d\x52\x57\x5c\x61\x66\x6b"
-                       "\x70\x75\x7a\x7f\x84\x89\x8e\x93"
-                       "\x98\x9d\xa2\xa7\xac\xb1\xb6\xbb"
-                       "\xc0\xc5\xca\xcf\xd4\xd9\xde\xe3"
-                       "\xe8\xed\xf2\xf7\xfc\x01\x06\x0b"
-                       "\x10\x15\x1a\x1f\x24\x29\x2e\x33"
-                       "\x38\x3d\x42\x47\x4c\x51\x56\x5b"
-                       "\x60\x65\x6a\x6f\x74\x79\x7e\x83"
-                       "\x88\x8d\x92\x97\x9c\xa1\xa6\xab"
-                       "\xb0\xb5\xba\xbf\xc4\xc9\xce\xd3"
-                       "\xd8\xdd\xe2\xe7\xec\xf1\xf6\xfb"
-                       "\x00\x07\x0e\x15\x1c\x23\x2a\x31"
-                       "\x38\x3f\x46\x4d\x54\x5b\x62\x69"
-                       "\x70\x77\x7e\x85\x8c\x93\x9a\xa1"
-                       "\xa8\xaf\xb6\xbd\xc4\xcb\xd2\xd9"
-                       "\xe0\xe7\xee\xf5\xfc\x03\x0a\x11"
-                       "\x18\x1f\x26\x2d\x34\x3b\x42\x49"
-                       "\x50\x57\x5e\x65\x6c\x73\x7a\x81"
-                       "\x88\x8f\x96\x9d\xa4\xab\xb2\xb9"
-                       "\xc0\xc7\xce\xd5\xdc\xe3\xea\xf1"
-                       "\xf8\xff\x06\x0d\x14\x1b\x22\x29"
-                       "\x30\x37\x3e\x45\x4c\x53\x5a\x61"
-                       "\x68\x6f\x76\x7d\x84\x8b\x92\x99"
-                       "\xa0\xa7\xae\xb5\xbc\xc3\xca\xd1"
-                       "\xd8\xdf\xe6\xed\xf4\xfb\x02\x09"
-                       "\x10\x17\x1e\x25\x2c\x33\x3a\x41"
-                       "\x48\x4f\x56\x5d\x64\x6b\x72\x79"
-                       "\x80\x87\x8e\x95\x9c\xa3\xaa\xb1"
-                       "\xb8\xbf\xc6\xcd\xd4\xdb\xe2\xe9"
-                       "\xf0\xf7\xfe\x05\x0c\x13\x1a\x21"
-                       "\x28\x2f\x36\x3d\x44\x4b\x52\x59"
-                       "\x60\x67\x6e\x75\x7c\x83\x8a\x91"
-                       "\x98\x9f\xa6\xad\xb4\xbb\xc2\xc9"
-                       "\xd0\xd7\xde\xe5\xec\xf3\xfa\x01"
-                       "\x08\x0f\x16\x1d\x24\x2b\x32\x39"
-                       "\x40\x47\x4e\x55\x5c\x63\x6a\x71"
-                       "\x78\x7f\x86\x8d\x94\x9b\xa2\xa9"
-                       "\xb0\xb7\xbe\xc5\xcc\xd3\xda\xe1"
-                       "\xe8\xef\xf6\xfd\x04\x0b\x12\x19"
-                       "\x20\x27\x2e\x35\x3c\x43\x4a\x51"
-                       "\x58\x5f\x66\x6d\x74\x7b\x82\x89"
-                       "\x90\x97\x9e\xa5\xac\xb3\xba\xc1"
-                       "\xc8\xcf\xd6\xdd\xe4\xeb\xf2\xf9"
-                       "\x00\x09\x12\x1b\x24\x2d\x36\x3f"
-                       "\x48\x51\x5a\x63\x6c\x75\x7e\x87"
-                       "\x90\x99\xa2\xab\xb4\xbd\xc6\xcf"
-                       "\xd8\xe1\xea\xf3\xfc\x05\x0e\x17"
-                       "\x20\x29\x32\x3b\x44\x4d\x56\x5f"
-                       "\x68\x71\x7a\x83\x8c\x95\x9e\xa7"
-                       "\xb0\xb9\xc2\xcb\xd4\xdd\xe6\xef"
-                       "\xf8\x01\x0a\x13\x1c\x25\x2e\x37"
-                       "\x40\x49\x52\x5b\x64\x6d\x76\x7f"
-                       "\x88\x91\x9a\xa3\xac\xb5\xbe\xc7"
-                       "\xd0\xd9\xe2\xeb\xf4\xfd\x06\x0f"
-                       "\x18\x21\x2a\x33\x3c\x45\x4e\x57"
-                       "\x60\x69\x72\x7b\x84\x8d\x96\x9f"
-                       "\xa8\xb1\xba\xc3\xcc\xd5\xde\xe7"
-                       "\xf0\xf9\x02\x0b\x14\x1d\x26\x2f"
-                       "\x38\x41\x4a\x53\x5c\x65\x6e\x77"
-                       "\x80\x89\x92\x9b\xa4\xad\xb6\xbf"
-                       "\xc8\xd1\xda\xe3\xec\xf5\xfe\x07"
-                       "\x10\x19\x22\x2b\x34\x3d\x46\x4f"
-                       "\x58\x61\x6a\x73\x7c\x85\x8e\x97"
-                       "\xa0\xa9\xb2\xbb\xc4\xcd\xd6\xdf"
-                       "\xe8\xf1\xfa\x03\x0c\x15\x1e\x27"
-                       "\x30\x39\x42\x4b\x54\x5d\x66\x6f"
-                       "\x78\x81\x8a\x93\x9c\xa5\xae\xb7"
-                       "\xc0\xc9\xd2\xdb\xe4\xed\xf6\xff"
-                       "\x08\x11\x1a\x23\x2c\x35\x3e\x47"
-                       "\x50\x59\x62\x6b\x74\x7d\x86\x8f"
-                       "\x98\xa1\xaa\xb3\xbc\xc5\xce\xd7"
-                       "\xe0\xe9\xf2\xfb\x04\x0d\x16\x1f"
-                       "\x28\x31\x3a\x43\x4c\x55\x5e\x67"
-                       "\x70\x79\x82\x8b\x94\x9d\xa6\xaf"
-                       "\xb8\xc1\xca\xd3\xdc\xe5\xee\xf7"
-                       "\x00\x0b\x16\x21\x2c\x37\x42\x4d"
-                       "\x58\x63\x6e\x79\x84\x8f\x9a\xa5"
-                       "\xb0\xbb\xc6\xd1\xdc\xe7\xf2\xfd"
-                       "\x08\x13\x1e\x29\x34\x3f\x4a\x55"
-                       "\x60\x6b\x76\x81\x8c\x97\xa2\xad"
-                       "\xb8\xc3\xce\xd9\xe4\xef\xfa\x05"
-                       "\x10\x1b\x26\x31\x3c\x47\x52\x5d"
-                       "\x68\x73\x7e\x89\x94\x9f\xaa\xb5"
-                       "\xc0\xcb\xd6\xe1\xec\xf7\x02\x0d"
-                       "\x18\x23\x2e\x39\x44\x4f\x5a\x65"
-                       "\x70\x7b\x86\x91\x9c\xa7\xb2\xbd"
-                       "\xc8\xd3\xde\xe9\xf4\xff\x0a\x15"
-                       "\x20\x2b\x36\x41\x4c\x57\x62\x6d"
-                       "\x78\x83\x8e\x99\xa4\xaf\xba\xc5"
-                       "\xd0\xdb\xe6\xf1\xfc\x07\x12\x1d"
-                       "\x28\x33\x3e\x49\x54\x5f\x6a\x75"
-                       "\x80\x8b\x96\xa1\xac\xb7\xc2\xcd"
-                       "\xd8\xe3\xee\xf9\x04\x0f\x1a\x25"
-                       "\x30\x3b\x46\x51\x5c\x67\x72\x7d"
-                       "\x88\x93\x9e\xa9\xb4\xbf\xca\xd5"
-                       "\xe0\xeb\xf6\x01\x0c\x17\x22\x2d"
-                       "\x38\x43\x4e\x59\x64\x6f\x7a\x85"
-                       "\x90\x9b\xa6\xb1\xbc\xc7\xd2\xdd"
-                       "\xe8\xf3\xfe\x09\x14\x1f\x2a\x35"
-                       "\x40\x4b\x56\x61\x6c\x77\x82\x8d"
-                       "\x98\xa3\xae\xb9\xc4\xcf\xda\xe5"
-                       "\xf0\xfb\x06\x11\x1c\x27\x32\x3d"
-                       "\x48\x53\x5e\x69\x74\x7f\x8a\x95"
-                       "\xa0\xab\xb6\xc1\xcc\xd7\xe2\xed"
-                       "\xf8\x03\x0e\x19\x24\x2f\x3a\x45"
-                       "\x50\x5b\x66\x71\x7c\x87\x92\x9d"
-                       "\xa8\xb3\xbe\xc9\xd4\xdf\xea\xf5"
-                       "\x00\x0d\x1a\x27\x34\x41\x4e\x5b"
-                       "\x68\x75\x82\x8f\x9c\xa9\xb6\xc3"
-                       "\xd0\xdd\xea\xf7\x04\x11\x1e\x2b"
-                       "\x38\x45\x52\x5f\x6c\x79\x86\x93"
-                       "\xa0\xad\xba\xc7\xd4\xe1\xee\xfb"
-                       "\x08\x15\x22\x2f\x3c\x49\x56\x63"
-                       "\x70\x7d\x8a\x97\xa4\xb1\xbe\xcb"
-                       "\xd8\xe5\xf2\xff\x0c\x19\x26\x33"
-                       "\x40\x4d\x5a\x67\x74\x81\x8e\x9b"
-                       "\xa8\xb5\xc2\xcf\xdc\xe9\xf6\x03"
-                       "\x10\x1d\x2a\x37\x44\x51\x5e\x6b"
-                       "\x78\x85\x92\x9f\xac\xb9\xc6\xd3"
-                       "\xe0\xed\xfa\x07\x14\x21\x2e\x3b"
-                       "\x48\x55\x62\x6f\x7c\x89\x96\xa3"
-                       "\xb0\xbd\xca\xd7\xe4\xf1\xfe\x0b"
-                       "\x18\x25\x32\x3f\x4c\x59\x66\x73"
-                       "\x80\x8d\x9a\xa7\xb4\xc1\xce\xdb"
-                       "\xe8\xf5\x02\x0f\x1c\x29\x36\x43"
-                       "\x50\x5d\x6a\x77\x84\x91\x9e\xab"
-                       "\xb8\xc5\xd2\xdf\xec\xf9\x06\x13"
-                       "\x20\x2d\x3a\x47\x54\x61\x6e\x7b"
-                       "\x88\x95\xa2\xaf\xbc\xc9\xd6\xe3"
-                       "\xf0\xfd\x0a\x17\x24\x31\x3e\x4b"
-                       "\x58\x65\x72\x7f\x8c\x99\xa6\xb3"
-                       "\xc0\xcd\xda\xe7\xf4\x01\x0e\x1b"
-                       "\x28\x35\x42\x4f\x5c\x69\x76\x83"
-                       "\x90\x9d\xaa\xb7\xc4\xd1\xde\xeb"
-                       "\xf8\x05\x12\x1f\x2c\x39\x46\x53"
-                       "\x60\x6d\x7a\x87\x94\xa1\xae\xbb"
-                       "\xc8\xd5\xe2\xef\xfc\x09\x16\x23"
-                       "\x30\x3d\x4a\x57\x64\x71\x7e\x8b"
-                       "\x98\xa5\xb2\xbf\xcc\xd9\xe6\xf3"
-                       "\x00\x0f\x1e\x2d\x3c\x4b\x5a\x69"
-                       "\x78\x87\x96\xa5\xb4\xc3\xd2\xe1"
-                       "\xf0\xff\x0e\x1d\x2c\x3b\x4a\x59"
-                       "\x68\x77\x86\x95\xa4\xb3\xc2\xd1"
-                       "\xe0\xef\xfe\x0d\x1c\x2b\x3a\x49"
-                       "\x58\x67\x76\x85\x94\xa3\xb2\xc1"
-                       "\xd0\xdf\xee\xfd\x0c\x1b\x2a\x39"
-                       "\x48\x57\x66\x75\x84\x93\xa2\xb1"
-                       "\xc0\xcf\xde\xed\xfc\x0b\x1a\x29"
-                       "\x38\x47\x56\x65\x74\x83\x92\xa1"
-                       "\xb0\xbf\xce\xdd\xec\xfb\x0a\x19"
-                       "\x28\x37\x46\x55\x64\x73\x82\x91"
-                       "\xa0\xaf\xbe\xcd\xdc\xeb\xfa\x09"
-                       "\x18\x27\x36\x45\x54\x63\x72\x81"
-                       "\x90\x9f\xae\xbd\xcc\xdb\xea\xf9"
-                       "\x08\x17\x26\x35\x44\x53\x62\x71"
-                       "\x80\x8f\x9e\xad\xbc\xcb\xda\xe9"
-                       "\xf8\x07\x16\x25\x34\x43\x52\x61"
-                       "\x70\x7f\x8e\x9d\xac\xbb\xca\xd9"
-                       "\xe8\xf7\x06\x15\x24\x33\x42\x51"
-                       "\x60\x6f\x7e\x8d\x9c\xab\xba\xc9"
-                       "\xd8\xe7\xf6\x05\x14\x23\x32\x41"
-                       "\x50\x5f\x6e\x7d\x8c\x9b\xaa\xb9"
-                       "\xc8\xd7\xe6\xf5\x04\x13\x22\x31"
-                       "\x40\x4f\x5e\x6d\x7c\x8b\x9a\xa9"
-                       "\xb8\xc7\xd6\xe5\xf4\x03\x12\x21"
-                       "\x30\x3f\x4e\x5d\x6c\x7b\x8a\x99"
-                       "\xa8\xb7\xc6\xd5\xe4\xf3\x02\x11"
-                       "\x20\x2f\x3e\x4d\x5c\x6b\x7a\x89"
-                       "\x98\xa7\xb6\xc5\xd4\xe3\xf2\x01"
-                       "\x10\x1f\x2e\x3d\x4c\x5b\x6a\x79"
-                       "\x88\x97\xa6\xb5\xc4\xd3\xe2\xf1"
-                       "\x00\x11\x22\x33\x44\x55\x66\x77"
-                       "\x88\x99\xaa\xbb\xcc\xdd\xee\xff"
-                       "\x10\x21\x32\x43\x54\x65\x76\x87"
-                       "\x98\xa9\xba\xcb\xdc\xed\xfe\x0f"
-                       "\x20\x31\x42\x53\x64\x75\x86\x97"
-                       "\xa8\xb9\xca\xdb\xec\xfd\x0e\x1f"
-                       "\x30\x41\x52\x63\x74\x85\x96\xa7"
-                       "\xb8\xc9\xda\xeb\xfc\x0d\x1e\x2f"
-                       "\x40\x51\x62\x73\x84\x95\xa6\xb7"
-                       "\xc8\xd9\xea\xfb\x0c\x1d\x2e\x3f"
-                       "\x50\x61\x72\x83\x94\xa5\xb6\xc7"
-                       "\xd8\xe9\xfa\x0b\x1c\x2d\x3e\x4f"
-                       "\x60\x71\x82\x93\xa4\xb5\xc6\xd7"
-                       "\xe8\xf9\x0a\x1b\x2c\x3d\x4e\x5f"
-                       "\x70\x81\x92\xa3\xb4\xc5\xd6\xe7"
-                       "\xf8\x09\x1a\x2b\x3c\x4d\x5e\x6f"
-                       "\x80\x91\xa2\xb3\xc4\xd5\xe6\xf7"
-                       "\x08\x19\x2a\x3b\x4c\x5d\x6e\x7f"
-                       "\x90\xa1\xb2\xc3\xd4\xe5\xf6\x07"
-                       "\x18\x29\x3a\x4b\x5c\x6d\x7e\x8f"
-                       "\xa0\xb1\xc2\xd3\xe4\xf5\x06\x17"
-                       "\x28\x39\x4a\x5b\x6c\x7d\x8e\x9f"
-                       "\xb0\xc1\xd2\xe3\xf4\x05\x16\x27"
-                       "\x38\x49\x5a\x6b\x7c\x8d\x9e\xaf"
-                       "\xc0\xd1\xe2\xf3\x04\x15\x26\x37"
-                       "\x48\x59\x6a\x7b\x8c\x9d\xae\xbf"
-                       "\xd0\xe1\xf2\x03\x14\x25\x36\x47"
-                       "\x58\x69\x7a\x8b\x9c\xad\xbe\xcf"
-                       "\xe0\xf1\x02\x13\x24\x35\x46\x57"
-                       "\x68\x79\x8a\x9b\xac\xbd\xce\xdf"
-                       "\xf0\x01\x12\x23\x34\x45\x56\x67"
-                       "\x78\x89\x9a\xab\xbc\xcd\xde\xef"
-                       "\x00\x13\x26\x39\x4c\x5f\x72\x85"
-                       "\x98\xab\xbe\xd1\xe4\xf7\x0a\x1d"
-                       "\x30\x43\x56\x69\x7c\x8f\xa2\xb5"
-                       "\xc8\xdb\xee\x01\x14\x27\x3a\x4d"
-                       "\x60\x73\x86\x99\xac\xbf\xd2\xe5"
-                       "\xf8\x0b\x1e\x31\x44\x57\x6a\x7d"
-                       "\x90\xa3\xb6\xc9\xdc\xef\x02\x15"
-                       "\x28\x3b\x4e\x61\x74\x87\x9a\xad"
-                       "\xc0\xd3\xe6\xf9\x0c\x1f\x32\x45"
-                       "\x58\x6b\x7e\x91\xa4\xb7\xca\xdd"
-                       "\xf0\x03\x16\x29\x3c\x4f\x62\x75"
-                       "\x88\x9b\xae\xc1\xd4\xe7\xfa\x0d"
-                       "\x20\x33\x46\x59\x6c\x7f\x92\xa5"
-                       "\xb8\xcb\xde\xf1\x04\x17\x2a\x3d"
-                       "\x50\x63\x76\x89\x9c\xaf\xc2\xd5"
-                       "\xe8\xfb\x0e\x21\x34\x47\x5a\x6d"
-                       "\x80\x93\xa6\xb9\xcc\xdf\xf2\x05"
-                       "\x18\x2b\x3e\x51\x64\x77\x8a\x9d"
-                       "\xb0\xc3\xd6\xe9\xfc\x0f\x22\x35"
-                       "\x48\x5b\x6e\x81\x94\xa7\xba\xcd"
-                       "\xe0\xf3\x06\x19\x2c\x3f\x52\x65"
-                       "\x78\x8b\x9e\xb1\xc4\xd7\xea\xfd"
-                       "\x10\x23\x36\x49\x5c\x6f\x82\x95"
-                       "\xa8\xbb\xce\xe1\xf4\x07\x1a\x2d"
-                       "\x40\x53\x66\x79\x8c\x9f\xb2\xc5"
-                       "\xd8\xeb\xfe\x11\x24\x37\x4a\x5d"
-                       "\x70\x83\x96\xa9\xbc\xcf\xe2\xf5"
-                       "\x08\x1b\x2e\x41\x54\x67\x7a\x8d"
-                       "\xa0\xb3\xc6\xd9\xec\xff\x12\x25"
-                       "\x38\x4b\x5e\x71\x84\x97\xaa\xbd"
-                       "\xd0\xe3\xf6\x09\x1c\x2f\x42\x55"
-                       "\x68\x7b\x8e\xa1\xb4\xc7\xda\xed"
-                       "\x00\x15\x2a\x3f\x54\x69\x7e\x93"
-                       "\xa8\xbd\xd2\xe7\xfc\x11\x26\x3b"
-                       "\x50\x65\x7a\x8f\xa4\xb9\xce\xe3"
-                       "\xf8\x0d\x22\x37\x4c\x61\x76\x8b"
-                       "\xa0\xb5\xca\xdf\xf4\x09\x1e\x33"
-                       "\x48\x5d\x72\x87\x9c\xb1\xc6\xdb"
-                       "\xf0\x05\x1a\x2f\x44\x59\x6e\x83"
-                       "\x98\xad\xc2\xd7\xec\x01\x16\x2b"
-                       "\x40\x55\x6a\x7f\x94\xa9\xbe\xd3"
-                       "\xe8\xfd\x12\x27\x3c\x51\x66\x7b"
-                       "\x90\xa5\xba\xcf\xe4\xf9\x0e\x23"
-                       "\x38\x4d\x62\x77\x8c\xa1\xb6\xcb"
-                       "\xe0\xf5\x0a\x1f\x34\x49\x5e\x73"
-                       "\x88\x9d\xb2\xc7\xdc\xf1\x06\x1b"
-                       "\x30\x45\x5a\x6f\x84\x99\xae\xc3"
-                       "\xd8\xed\x02\x17\x2c\x41\x56\x6b"
-                       "\x80\x95\xaa\xbf\xd4\xe9\xfe\x13"
-                       "\x28\x3d\x52\x67\x7c\x91\xa6\xbb"
-                       "\xd0\xe5\xfa\x0f\x24\x39\x4e\x63"
-                       "\x78\x8d\xa2\xb7\xcc\xe1\xf6\x0b"
-                       "\x20\x35\x4a\x5f\x74\x89\x9e\xb3"
-                       "\xc8\xdd\xf2\x07\x1c\x31\x46\x5b"
-                       "\x70\x85\x9a\xaf\xc4\xd9\xee\x03"
-                       "\x18\x2d\x42\x57\x6c\x81\x96\xab"
-                       "\xc0\xd5\xea\xff\x14\x29\x3e\x53"
-                       "\x68\x7d\x92\xa7\xbc\xd1\xe6\xfb"
-                       "\x10\x25\x3a\x4f\x64\x79\x8e\xa3"
-                       "\xb8\xcd\xe2\xf7\x0c\x21\x36\x4b"
-                       "\x60\x75\x8a\x9f\xb4\xc9\xde\xf3"
-                       "\x08\x1d\x32\x47\x5c\x71\x86\x9b"
-                       "\xb0\xc5\xda\xef\x04\x19\x2e\x43"
-                       "\x58\x6d\x82\x97\xac\xc1\xd6\xeb"
-                       "\x00\x17\x2e\x45\x5c\x73\x8a\xa1"
-                       "\xb8\xcf\xe6\xfd\x14\x2b\x42\x59"
-                       "\x70\x87\x9e\xb5\xcc\xe3\xfa\x11"
-                       "\x28\x3f\x56\x6d\x84\x9b\xb2\xc9"
-                       "\xe0\xf7\x0e\x25\x3c\x53\x6a\x81"
-                       "\x98\xaf\xc6\xdd\xf4\x0b\x22\x39"
-                       "\x50\x67\x7e\x95\xac\xc3\xda\xf1"
-                       "\x08\x1f\x36\x4d\x64\x7b\x92\xa9"
-                       "\xc0\xd7\xee\x05\x1c\x33\x4a\x61"
-                       "\x78\x8f\xa6\xbd\xd4\xeb\x02\x19"
-                       "\x30\x47\x5e\x75\x8c\xa3\xba\xd1"
-                       "\xe8\xff\x16\x2d\x44\x5b\x72\x89"
-                       "\xa0\xb7\xce\xe5\xfc\x13\x2a\x41"
-                       "\x58\x6f\x86\x9d\xb4\xcb\xe2\xf9"
-                       "\x10\x27\x3e\x55\x6c\x83\x9a\xb1"
-                       "\xc8\xdf\xf6\x0d\x24\x3b\x52\x69"
-                       "\x80\x97\xae\xc5\xdc\xf3\x0a\x21"
-                       "\x38\x4f\x66\x7d\x94\xab\xc2\xd9"
-                       "\xf0\x07\x1e\x35\x4c\x63\x7a\x91"
-                       "\xa8\xbf\xd6\xed\x04\x1b\x32\x49"
-                       "\x60\x77\x8e\xa5\xbc\xd3\xea\x01"
-                       "\x18\x2f\x46\x5d\x74\x8b\xa2\xb9"
-                       "\xd0\xe7\xfe\x15\x2c\x43\x5a\x71"
-                       "\x88\x9f\xb6\xcd\xe4\xfb\x12\x29"
-                       "\x40\x57\x6e\x85\x9c\xb3\xca\xe1"
-                       "\xf8\x0f\x26\x3d\x54\x6b\x82\x99"
-                       "\xb0\xc7\xde\xf5\x0c\x23\x3a\x51"
-                       "\x68\x7f\x96\xad\xc4\xdb\xf2\x09"
-                       "\x20\x37\x4e\x65\x7c\x93\xaa\xc1"
-                       "\xd8\xef\x06\x1d\x34\x4b\x62\x79"
-                       "\x90\xa7\xbe\xd5\xec\x03\x1a\x31"
-                       "\x48\x5f\x76\x8d\xa4\xbb\xd2\xe9"
-                       "\x00\x19\x32\x4b\x64\x7d\x96\xaf"
-                       "\xc8\xe1\xfa\x13\x2c\x45\x5e\x77"
-                       "\x90\xa9\xc2\xdb\xf4\x0d\x26\x3f"
-                       "\x58\x71\x8a\xa3\xbc\xd5\xee\x07"
-                       "\x20\x39\x52\x6b\x84\x9d\xb6\xcf"
-                       "\xe8\x01\x1a\x33\x4c\x65\x7e\x97"
-                       "\xb0\xc9\xe2\xfb\x14\x2d\x46\x5f"
-                       "\x78\x91\xaa\xc3\xdc\xf5\x0e\x27"
-                       "\x40\x59\x72\x8b\xa4\xbd\xd6\xef"
-                       "\x08\x21\x3a\x53\x6c\x85\x9e\xb7"
-                       "\xd0\xe9\x02\x1b\x34\x4d\x66\x7f"
-                       "\x98\xb1\xca\xe3\xfc\x15\x2e\x47"
-                       "\x60\x79\x92\xab\xc4\xdd\xf6\x0f"
-                       "\x28\x41\x5a\x73\x8c\xa5\xbe\xd7"
-                       "\xf0\x09\x22\x3b\x54\x6d\x86\x9f"
-                       "\xb8\xd1\xea\x03\x1c\x35\x4e\x67"
-                       "\x80\x99\xb2\xcb\xe4\xfd\x16\x2f"
-                       "\x48\x61\x7a\x93\xac\xc5\xde\xf7"
-                       "\x10\x29\x42\x5b\x74\x8d\xa6\xbf"
-                       "\xd8\xf1\x0a\x23\x3c\x55\x6e\x87"
-                       "\xa0\xb9\xd2\xeb\x04\x1d\x36\x4f"
-                       "\x68\x81\x9a\xb3\xcc\xe5\xfe\x17"
-                       "\x30\x49\x62\x7b\x94\xad\xc6\xdf"
-                       "\xf8\x11\x2a\x43\x5c\x75\x8e\xa7"
-                       "\xc0\xd9\xf2\x0b\x24\x3d\x56\x6f"
-                       "\x88\xa1\xba\xd3\xec\x05\x1e\x37"
-                       "\x50\x69\x82\x9b\xb4\xcd\xe6\xff"
-                       "\x18\x31\x4a\x63\x7c\x95\xae\xc7"
-                       "\xe0\xf9\x12\x2b\x44\x5d\x76\x8f"
-                       "\xa8\xc1\xda\xf3\x0c\x25\x3e\x57"
-                       "\x70\x89\xa2\xbb\xd4\xed\x06\x1f"
-                       "\x38\x51\x6a\x83\x9c\xb5\xce\xe7"
-                       "\x00\x1b\x36\x51\x6c\x87\xa2\xbd"
-                       "\xd8\xf3\x0e\x29\x44\x5f\x7a\x95"
-                       "\xb0\xcb\xe6\x01\x1c\x37\x52\x6d"
-                       "\x88\xa3\xbe\xd9\xf4\x0f\x2a\x45"
-                       "\x60\x7b\x96\xb1\xcc\xe7\x02\x1d"
-                       "\x38\x53\x6e\x89\xa4\xbf\xda\xf5"
-                       "\x10\x2b\x46\x61\x7c\x97\xb2\xcd"
-                       "\xe8\x03\x1e\x39\x54\x6f\x8a\xa5"
-                       "\xc0\xdb\xf6\x11\x2c\x47\x62\x7d"
-                       "\x98\xb3\xce\xe9\x04\x1f\x3a\x55"
-                       "\x70\x8b\xa6\xc1\xdc\xf7\x12\x2d"
-                       "\x48\x63\x7e\x99\xb4\xcf\xea\x05"
-                       "\x20\x3b\x56\x71\x8c\xa7\xc2\xdd"
-                       "\xf8\x13\x2e\x49\x64\x7f\x9a\xb5"
-                       "\xd0\xeb\x06\x21\x3c\x57\x72\x8d"
-                       "\xa8\xc3\xde\xf9\x14\x2f\x4a\x65"
-                       "\x80\x9b\xb6\xd1\xec\x07\x22\x3d"
-                       "\x58\x73\x8e\xa9\xc4\xdf\xfa\x15"
-                       "\x30\x4b\x66\x81\x9c\xb7\xd2\xed"
-                       "\x08\x23\x3e\x59\x74\x8f\xaa\xc5"
-                       "\xe0\xfb\x16\x31\x4c\x67\x82\x9d"
-                       "\xb8\xd3\xee\x09\x24\x3f\x5a\x75"
-                       "\x90\xab\xc6\xe1\xfc\x17\x32\x4d"
-                       "\x68\x83\x9e\xb9\xd4\xef\x0a\x25"
-                       "\x40\x5b\x76\x91\xac\xc7\xe2\xfd"
-                       "\x18\x33\x4e\x69\x84\x9f\xba\xd5"
-                       "\xf0\x0b\x26\x41\x5c\x77\x92\xad"
-                       "\xc8\xe3\xfe\x19\x34\x4f\x6a\x85"
-                       "\xa0\xbb\xd6\xf1\x0c\x27\x42\x5d"
-                       "\x78\x93\xae\xc9\xe4\xff\x1a\x35"
-                       "\x50\x6b\x86\xa1\xbc\xd7\xf2\x0d"
-                       "\x28\x43\x5e\x79\x94\xaf\xca\xe5"
-                       "\x00\x1d\x3a\x57\x74\x91\xae\xcb"
-                       "\xe8\x05\x22\x3f\x5c\x79\x96\xb3"
-                       "\xd0\xed\x0a\x27\x44\x61\x7e\x9b"
-                       "\xb8\xd5\xf2\x0f\x2c\x49\x66\x83"
-                       "\xa0\xbd\xda\xf7\x14\x31\x4e\x6b"
-                       "\x88\xa5\xc2\xdf\xfc\x19\x36\x53"
-                       "\x70\x8d\xaa\xc7\xe4\x01\x1e\x3b"
-                       "\x58\x75\x92\xaf\xcc\xe9\x06\x23"
-                       "\x40\x5d\x7a\x97\xb4\xd1\xee\x0b"
-                       "\x28\x45\x62\x7f\x9c\xb9\xd6\xf3"
-                       "\x10\x2d\x4a\x67\x84\xa1\xbe\xdb"
-                       "\xf8\x15\x32\x4f\x6c\x89\xa6\xc3"
-                       "\xe0\xfd\x1a\x37\x54\x71\x8e\xab"
-                       "\xc8\xe5\x02\x1f\x3c\x59\x76\x93"
-                       "\xb0\xcd\xea\x07\x24\x41\x5e\x7b"
-                       "\x98\xb5\xd2\xef\x0c\x29\x46\x63"
-                       "\x80\x9d\xba\xd7\xf4\x11\x2e\x4b"
-                       "\x68\x85\xa2\xbf\xdc\xf9\x16\x33"
-                       "\x50\x6d\x8a\xa7\xc4\xe1\xfe\x1b"
-                       "\x38\x55\x72\x8f\xac\xc9\xe6\x03"
-                       "\x20\x3d\x5a\x77\x94\xb1\xce\xeb"
-                       "\x08\x25\x42\x5f\x7c\x99\xb6\xd3"
-                       "\xf0\x0d\x2a\x47\x64\x81\x9e\xbb"
-                       "\xd8\xf5\x12\x2f\x4c\x69\x86\xa3"
-                       "\xc0\xdd\xfa\x17\x34\x51\x6e\x8b"
-                       "\xa8\xc5\xe2\xff\x1c\x39\x56\x73"
-                       "\x90\xad\xca\xe7\x04\x21\x3e\x5b"
-                       "\x78\x95\xb2\xcf\xec\x09\x26\x43"
-                       "\x60\x7d\x9a\xb7\xd4\xf1\x0e\x2b"
-                       "\x48\x65\x82\x9f\xbc\xd9\xf6\x13"
-                       "\x30\x4d\x6a\x87\xa4\xc1\xde\xfb"
-                       "\x18\x35\x52\x6f\x8c\xa9\xc6\xe3"
-                       "\x00\x1f\x3e\x5d\x7c\x9b\xba\xd9"
-                       "\xf8\x17\x36\x55\x74\x93\xb2\xd1"
-                       "\xf0\x0f\x2e\x4d\x6c\x8b\xaa\xc9"
-                       "\xe8\x07\x26\x45\x64\x83\xa2\xc1"
-                       "\xe0\xff\x1e\x3d\x5c\x7b\x9a\xb9"
-                       "\xd8\xf7\x16\x35\x54\x73\x92\xb1"
-                       "\xd0\xef\x0e\x2d\x4c\x6b\x8a\xa9"
-                       "\xc8\xe7\x06\x25\x44\x63\x82\xa1"
-                       "\xc0\xdf\xfe\x1d\x3c\x5b\x7a\x99"
-                       "\xb8\xd7\xf6\x15\x34\x53\x72\x91"
-                       "\xb0\xcf\xee\x0d\x2c\x4b\x6a\x89"
-                       "\xa8\xc7\xe6\x05\x24\x43\x62\x81"
-                       "\xa0\xbf\xde\xfd\x1c\x3b\x5a\x79"
-                       "\x98\xb7\xd6\xf5\x14\x33\x52\x71"
-                       "\x90\xaf\xce\xed\x0c\x2b\x4a\x69"
-                       "\x88\xa7\xc6\xe5\x04\x23\x42\x61"
-                       "\x80\x9f\xbe\xdd\xfc\x1b\x3a\x59"
-                       "\x78\x97\xb6\xd5\xf4\x13\x32\x51"
-                       "\x70\x8f\xae\xcd\xec\x0b\x2a\x49"
-                       "\x68\x87\xa6\xc5\xe4\x03\x22\x41"
-                       "\x60\x7f\x9e\xbd\xdc\xfb\x1a\x39"
-                       "\x58\x77\x96\xb5\xd4\xf3\x12\x31"
-                       "\x50\x6f\x8e\xad\xcc\xeb\x0a\x29"
-                       "\x48\x67\x86\xa5\xc4\xe3\x02\x21"
-                       "\x40\x5f\x7e\x9d\xbc\xdb\xfa\x19"
-                       "\x38\x57\x76\x95\xb4\xd3\xf2\x11"
-                       "\x30\x4f\x6e\x8d\xac\xcb\xea\x09"
-                       "\x28\x47\x66\x85\xa4\xc3\xe2\x01"
-                       "\x20\x3f\x5e\x7d\x9c\xbb\xda\xf9"
-                       "\x18\x37\x56\x75\x94\xb3\xd2\xf1"
-                       "\x10\x2f\x4e\x6d\x8c\xab\xca\xe9"
-                       "\x08\x27\x46\x65\x84\xa3\xc2\xe1"
-                       "\x00\x21\x42\x63",
-               .ilen = 4100,
-               .result =
-                       "\xb5\x81\xf5\x64\x18\x73\xe3\xf0"
-                       "\x4c\x13\xf2\x77\x18\x60\x65\x5e"
-                       "\x29\x01\xce\x98\x55\x53\xf9\x0c"
-                       "\x2a\x08\xd5\x09\xb3\x57\x55\x56"
-                       "\xc5\xe9\x56\x90\xcb\x6a\xa3\xc0"
-                       "\xff\xc4\x79\xb4\xd2\x97\x5d\xc4"
-                       "\x43\xd1\xfe\x94\x7b\x88\x06\x5a"
-                       "\xb2\x9e\x2c\xfc\x44\x03\xb7\x90"
-                       "\xa0\xc1\xba\x6a\x33\xb8\xc7\xb2"
-                       "\x9d\xe1\x12\x4f\xc0\x64\xd4\x01"
-                       "\xfe\x8c\x7a\x66\xf7\xe6\x5a\x91"
-                       "\xbb\xde\x56\x86\xab\x65\x21\x30"
-                       "\x00\x84\x65\x24\xa5\x7d\x85\xb4"
-                       "\xe3\x17\xed\x3a\xb7\x6f\xb4\x0b"
-                       "\x0b\xaf\x15\xae\x5a\x8f\xf2\x0c"
-                       "\x2f\x27\xf4\x09\xd8\xd2\x96\xb7"
-                       "\x71\xf2\xc5\x99\x4d\x7e\x7f\x75"
-                       "\x77\x89\x30\x8b\x59\xdb\xa2\xb2"
-                       "\xa0\xf3\x19\x39\x2b\xc5\x7e\x3f"
-                       "\x4f\xd9\xd3\x56\x28\x97\x44\xdc"
-                       "\xc0\x8b\x77\x24\xd9\x52\xe7\xc5"
-                       "\xaf\xf6\x7d\x59\xb2\x44\x05\x1d"
-                       "\xb1\xb0\x11\xa5\x0f\xec\x33\xe1"
-                       "\x6d\x1b\x4e\x1f\xff\x57\x91\xb4"
-                       "\x5b\x9a\x96\xc5\x53\xbc\xae\x20"
-                       "\x3c\xbb\x14\xe2\xe8\x22\x33\xc1"
-                       "\x5e\x76\x9e\x46\x99\xf6\x2a\x15"
-                       "\xc6\x97\x02\xa0\x66\x43\xd1\xa6"
-                       "\x31\xa6\x9f\xfb\xf4\xd3\x69\xe5"
-                       "\xcd\x76\x95\xb8\x7a\x82\x7f\x21"
-                       "\x45\xff\x3f\xce\x55\xf6\x95\x10"
-                       "\x08\x77\x10\x43\xc6\xf3\x09\xe5"
-                       "\x68\xe7\x3c\xad\x00\x52\x45\x0d"
-                       "\xfe\x2d\xc6\xc2\x94\x8c\x12\x1d"
-                       "\xe6\x25\xae\x98\x12\x8e\x19\x9c"
-                       "\x81\x68\xb1\x11\xf6\x69\xda\xe3"
-                       "\x62\x08\x18\x7a\x25\x49\x28\xac"
-                       "\xba\x71\x12\x0b\xe4\xa2\xe5\xc7"
-                       "\x5d\x8e\xec\x49\x40\x21\xbf\x5a"
-                       "\x98\xf3\x02\x68\x55\x03\x7f\x8a"
-                       "\xe5\x94\x0c\x32\x5c\x07\x82\x63"
-                       "\xaf\x6f\x91\x40\x84\x8e\x52\x25"
-                       "\xd0\xb0\x29\x53\x05\xe2\x50\x7a"
-                       "\x34\xeb\xc9\x46\x20\xa8\x3d\xde"
-                       "\x7f\x16\x5f\x36\xc5\x2e\xdc\xd1"
-                       "\x15\x47\xc7\x50\x40\x6d\x91\xc5"
-                       "\xe7\x93\x95\x1a\xd3\x57\xbc\x52"
-                       "\x33\xee\x14\x19\x22\x52\x89\xa7"
-                       "\x4a\x25\x56\x77\x4b\xca\xcf\x0a"
-                       "\xe1\xf5\x35\x85\x30\x7e\x59\x4a"
-                       "\xbd\x14\x5b\xdf\xe3\x46\xcb\xac"
-                       "\x1f\x6c\x96\x0e\xf4\x81\xd1\x99"
-                       "\xca\x88\x63\x3d\x02\x58\x6b\xa9"
-                       "\xe5\x9f\xb3\x00\xb2\x54\xc6\x74"
-                       "\x1c\xbf\x46\xab\x97\xcc\xf8\x54"
-                       "\x04\x07\x08\x52\xe6\xc0\xda\x93"
-                       "\x74\x7d\x93\x99\x5d\x78\x68\xa6"
-                       "\x2e\x6b\xd3\x6a\x69\xcc\x12\x6b"
-                       "\xd4\xc7\xa5\xc6\xe7\xf6\x03\x04"
-                       "\x5d\xcd\x61\x5e\x17\x40\xdc\xd1"
-                       "\x5c\xf5\x08\xdf\x5c\x90\x85\xa4"
-                       "\xaf\xf6\x78\xbb\x0d\xf1\xf4\xa4"
-                       "\x54\x26\x72\x9e\x61\xfa\x86\xcf"
-                       "\xe8\x9e\xa1\xe0\xc7\x48\x23\xae"
-                       "\x5a\x90\xae\x75\x0a\x74\x18\x89"
-                       "\x05\xb1\x92\xb2\x7f\xd0\x1b\xa6"
-                       "\x62\x07\x25\x01\xc7\xc2\x4f\xf9"
-                       "\xe8\xfe\x63\x95\x80\x07\xb4\x26"
-                       "\xcc\xd1\x26\xb6\xc4\x3f\x9e\xcb"
-                       "\x8e\x3b\x2e\x44\x16\xd3\x10\x9a"
-                       "\x95\x08\xeb\xc8\xcb\xeb\xbf\x6f"
-                       "\x0b\xcd\x1f\xc8\xca\x86\xaa\xec"
-                       "\x33\xe6\x69\xf4\x45\x25\x86\x3a"
-                       "\x22\x94\x4f\x00\x23\x6a\x44\xc2"
-                       "\x49\x97\x33\xab\x36\x14\x0a\x70"
-                       "\x24\xc3\xbe\x04\x3b\x79\xa0\xf9"
-                       "\xb8\xe7\x76\x29\x22\x83\xd7\xf2"
-                       "\x94\xf4\x41\x49\xba\x5f\x7b\x07"
-                       "\xb5\xfb\xdb\x03\x1a\x9f\xb6\x4c"
-                       "\xc2\x2e\x37\x40\x49\xc3\x38\x16"
-                       "\xe2\x4f\x77\x82\xb0\x68\x4c\x71"
-                       "\x1d\x57\x61\x9c\xd9\x4e\x54\x99"
-                       "\x47\x13\x28\x73\x3c\xbb\x00\x90"
-                       "\xf3\x4d\xc9\x0e\xfd\xe7\xb1\x71"
-                       "\xd3\x15\x79\xbf\xcc\x26\x2f\xbd"
-                       "\xad\x6c\x50\x69\x6c\x3e\x6d\x80"
-                       "\x9a\xea\x78\xaf\x19\xb2\x0d\x4d"
-                       "\xad\x04\x07\xae\x22\x90\x4a\x93"
-                       "\x32\x0e\x36\x9b\x1b\x46\xba\x3b"
-                       "\xb4\xac\xc6\xd1\xa2\x31\x53\x3b"
-                       "\x2a\x3d\x45\xfe\x03\x61\x10\x85"
-                       "\x17\x69\xa6\x78\xcc\x6c\x87\x49"
-                       "\x53\xf9\x80\x10\xde\x80\xa2\x41"
-                       "\x6a\xc3\x32\x02\xad\x6d\x3c\x56"
-                       "\x00\x71\x51\x06\xa7\xbd\xfb\xef"
-                       "\x3c\xb5\x9f\xfc\x48\x7d\x53\x7c"
-                       "\x66\xb0\x49\x23\xc4\x47\x10\x0e"
-                       "\xe5\x6c\x74\x13\xe6\xc5\x3f\xaa"
-                       "\xde\xff\x07\x44\xdd\x56\x1b\xad"
-                       "\x09\x77\xfb\x5b\x12\xb8\x0d\x38"
-                       "\x17\x37\x35\x7b\x9b\xbc\xfe\xd4"
-                       "\x7e\x8b\xda\x7e\x5b\x04\xa7\x22"
-                       "\xa7\x31\xa1\x20\x86\xc7\x1b\x99"
-                       "\xdb\xd1\x89\xf4\x94\xa3\x53\x69"
-                       "\x8d\xe7\xe8\x74\x11\x8d\x74\xd6"
-                       "\x07\x37\x91\x9f\xfd\x67\x50\x3a"
-                       "\xc9\xe1\xf4\x36\xd5\xa0\x47\xd1"
-                       "\xf9\xe5\x39\xa3\x31\xac\x07\x36"
-                       "\x23\xf8\x66\x18\x14\x28\x34\x0f"
-                       "\xb8\xd0\xe7\x29\xb3\x04\x4b\x55"
-                       "\x01\x41\xb2\x75\x8d\xcb\x96\x85"
-                       "\x3a\xfb\xab\x2b\x9e\xfa\x58\x20"
-                       "\x44\x1f\xc0\x14\x22\x75\x61\xe8"
-                       "\xaa\x19\xcf\xf1\x82\x56\xf4\xd7"
-                       "\x78\x7b\x3d\x5f\xb3\x9e\x0b\x8a"
-                       "\x57\x50\xdb\x17\x41\x65\x4d\xa3"
-                       "\x02\xc9\x9c\x9c\x53\xfb\x39\x39"
-                       "\x9b\x1d\x72\x24\xda\xb7\x39\xbe"
-                       "\x13\x3b\xfa\x29\xda\x9e\x54\x64"
-                       "\x6e\xba\xd8\xa1\xcb\xb3\x36\xfa"
-                       "\xcb\x47\x85\xe9\x61\x38\xbc\xbe"
-                       "\xc5\x00\x38\x2a\x54\xf7\xc4\xb9"
-                       "\xb3\xd3\x7b\xa0\xa0\xf8\x72\x7f"
-                       "\x8c\x8e\x82\x0e\xc6\x1c\x75\x9d"
-                       "\xca\x8e\x61\x87\xde\xad\x80\xd2"
-                       "\xf5\xf9\x80\xef\x15\x75\xaf\xf5"
-                       "\x80\xfb\xff\x6d\x1e\x25\xb7\x40"
-                       "\x61\x6a\x39\x5a\x6a\xb5\x31\xab"
-                       "\x97\x8a\x19\x89\x44\x40\xc0\xa6"
-                       "\xb4\x4e\x30\x32\x7b\x13\xe7\x67"
-                       "\xa9\x8b\x57\x04\xc2\x01\xa6\xf4"
-                       "\x28\x99\xad\x2c\x76\xa3\x78\xc2"
-                       "\x4a\xe6\xca\x5c\x50\x6a\xc1\xb0"
-                       "\x62\x4b\x10\x8e\x7c\x17\x43\xb3"
-                       "\x17\x66\x1c\x3e\x8d\x69\xf0\x5a"
-                       "\x71\xf5\x97\xdc\xd1\x45\xdd\x28"
-                       "\xf3\x5d\xdf\x53\x7b\x11\xe5\xbc"
-                       "\x4c\xdb\x1b\x51\x6b\xe9\xfb\x3d"
-                       "\xc1\xc3\x2c\xb9\x71\xf5\xb6\xb2"
-                       "\x13\x36\x79\x80\x53\xe8\xd3\xa6"
-                       "\x0a\xaf\xfd\x56\x97\xf7\x40\x8e"
-                       "\x45\xce\xf8\xb0\x9e\x5c\x33\x82"
-                       "\xb0\x44\x56\xfc\x05\x09\xe9\x2a"
-                       "\xac\x26\x80\x14\x1d\xc8\x3a\x35"
-                       "\x4c\x82\x97\xfd\x76\xb7\xa9\x0a"
-                       "\x35\x58\x79\x8e\x0f\x66\xea\xaf"
-                       "\x51\x6c\x09\xa9\x6e\x9b\xcb\x9a"
-                       "\x31\x47\xa0\x2f\x7c\x71\xb4\x4a"
-                       "\x11\xaa\x8c\x66\xc5\x64\xe6\x3a"
-                       "\x54\xda\x24\x6a\xc4\x41\x65\x46"
-                       "\x82\xa0\x0a\x0f\x5f\xfb\x25\xd0"
-                       "\x2c\x91\xa7\xee\xc4\x81\x07\x86"
-                       "\x75\x5e\x33\x69\x97\xe4\x2c\xa8"
-                       "\x9d\x9f\x0b\x6a\xbe\xad\x98\xda"
-                       "\x6d\x94\x41\xda\x2c\x1e\x89\xc4"
-                       "\xc2\xaf\x1e\x00\x05\x0b\x83\x60"
-                       "\xbd\x43\xea\x15\x23\x7f\xb9\xac"
-                       "\xee\x4f\x2c\xaf\x2a\xf3\xdf\xd0"
-                       "\xf3\x19\x31\xbb\x4a\x74\x84\x17"
-                       "\x52\x32\x2c\x7d\x61\xe4\xcb\xeb"
-                       "\x80\x38\x15\x52\xcb\x6f\xea\xe5"
-                       "\x73\x9c\xd9\x24\x69\xc6\x95\x32"
-                       "\x21\xc8\x11\xe4\xdc\x36\xd7\x93"
-                       "\x38\x66\xfb\xb2\x7f\x3a\xb9\xaf"
-                       "\x31\xdd\x93\x75\x78\x8a\x2c\x94"
-                       "\x87\x1a\x58\xec\x9e\x7d\x4d\xba"
-                       "\xe1\xe5\x4d\xfc\xbc\xa4\x2a\x14"
-                       "\xef\xcc\xa7\xec\xab\x43\x09\x18"
-                       "\xd3\xab\x68\xd1\x07\x99\x44\x47"
-                       "\xd6\x83\x85\x3b\x30\xea\xa9\x6b"
-                       "\x63\xea\xc4\x07\xfb\x43\x2f\xa4"
-                       "\xaa\xb0\xab\x03\x89\xce\x3f\x8c"
-                       "\x02\x7c\x86\x54\xbc\x88\xaf\x75"
-                       "\xd2\xdc\x63\x17\xd3\x26\xf6\x96"
-                       "\xa9\x3c\xf1\x61\x8c\x11\x18\xcc"
-                       "\xd6\xea\x5b\xe2\xcd\xf0\xf1\xb2"
-                       "\xe5\x35\x90\x1f\x85\x4c\x76\x5b"
-                       "\x66\xce\x44\xa4\x32\x9f\xe6\x7b"
-                       "\x71\x6e\x9f\x58\x15\x67\x72\x87"
-                       "\x64\x8e\x3a\x44\x45\xd4\x76\xfa"
-                       "\xc2\xf6\xef\x85\x05\x18\x7a\x9b"
-                       "\xba\x41\x54\xac\xf0\xfc\x59\x12"
-                       "\x3f\xdf\xa0\xe5\x8a\x65\xfd\x3a"
-                       "\x62\x8d\x83\x2c\x03\xbe\x05\x76"
-                       "\x2e\x53\x49\x97\x94\x33\xae\x40"
-                       "\x81\x15\xdb\x6e\xad\xaa\xf5\x4b"
-                       "\xe3\x98\x70\xdf\xe0\x7c\xcd\xdb"
-                       "\x02\xd4\x7d\x2f\xc1\xe6\xb4\xf3"
-                       "\xd7\x0d\x7a\xd9\x23\x9e\x87\x2d"
-                       "\xce\x87\xad\xcc\x72\x05\x00\x29"
-                       "\xdc\x73\x7f\x64\xc1\x15\x0e\xc2"
-                       "\xdf\xa7\x5f\xeb\x41\xa1\xcd\xef"
-                       "\x5c\x50\x79\x2a\x56\x56\x71\x8c"
-                       "\xac\xc0\x79\x50\x69\xca\x59\x32"
-                       "\x65\xf2\x54\xe4\x52\x38\x76\xd1"
-                       "\x5e\xde\x26\x9e\xfb\x75\x2e\x11"
-                       "\xb5\x10\xf4\x17\x73\xf5\x89\xc7"
-                       "\x4f\x43\x5c\x8e\x7c\xb9\x05\x52"
-                       "\x24\x40\x99\xfe\x9b\x85\x0b\x6c"
-                       "\x22\x3e\x8b\xae\x86\xa1\xd2\x79"
-                       "\x05\x68\x6b\xab\xe3\x41\x49\xed"
-                       "\x15\xa1\x8d\x40\x2d\x61\xdf\x1a"
-                       "\x59\xc9\x26\x8b\xef\x30\x4c\x88"
-                       "\x4b\x10\xf8\x8d\xa6\x92\x9f\x4b"
-                       "\xf3\xc4\x53\x0b\x89\x5d\x28\x92"
-                       "\xcf\x78\xb2\xc0\x5d\xed\x7e\xfc"
-                       "\xc0\x12\x23\x5f\x5a\x78\x86\x43"
-                       "\x6e\x27\xf7\x5a\xa7\x6a\xed\x19"
-                       "\x04\xf0\xb3\x12\xd1\xbd\x0e\x89"
-                       "\x6e\xbc\x96\xa8\xd8\x49\x39\x9f"
-                       "\x7e\x67\xf0\x2e\x3e\x01\xa9\xba"
-                       "\xec\x8b\x62\x8e\xcb\x4a\x70\x43"
-                       "\xc7\xc2\xc4\xca\x82\x03\x73\xe9"
-                       "\x11\xdf\xcf\x54\xea\xc9\xb0\x95"
-                       "\x51\xc0\x13\x3d\x92\x05\xfa\xf4"
-                       "\xa9\x34\xc8\xce\x6c\x3d\x54\xcc"
-                       "\xc4\xaf\xf1\xdc\x11\x44\x26\xa2"
-                       "\xaf\xf1\x85\x75\x7d\x03\x61\x68"
-                       "\x4e\x78\xc6\x92\x7d\x86\x7d\x77"
-                       "\xdc\x71\x72\xdb\xc6\xae\xa1\xcb"
-                       "\x70\x9a\x0b\x19\xbe\x4a\x6c\x2a"
-                       "\xe2\xba\x6c\x64\x9a\x13\x28\xdf"
-                       "\x85\x75\xe6\x43\xf6\x87\x08\x68"
-                       "\x6e\xba\x6e\x79\x9f\x04\xbc\x23"
-                       "\x50\xf6\x33\x5c\x1f\x24\x25\xbe"
-                       "\x33\x47\x80\x45\x56\xa3\xa7\xd7"
-                       "\x7a\xb1\x34\x0b\x90\x3c\x9c\xad"
-                       "\x44\x5f\x9e\x0e\x9d\xd4\xbd\x93"
-                       "\x5e\xfa\x3c\xe0\xb0\xd9\xed\xf3"
-                       "\xd6\x2e\xff\x24\xd8\x71\x6c\xed"
-                       "\xaf\x55\xeb\x22\xac\x93\x68\x32"
-                       "\x05\x5b\x47\xdd\xc6\x4a\xcb\xc7"
-                       "\x10\xe1\x3c\x92\x1a\xf3\x23\x78"
-                       "\x2b\xa1\xd2\x80\xf4\x12\xb1\x20"
-                       "\x8f\xff\x26\x35\xdd\xfb\xc7\x4e"
-                       "\x78\xf1\x2d\x50\x12\x77\xa8\x60"
-                       "\x7c\x0f\xf5\x16\x2f\x63\x70\x2a"
-                       "\xc0\x96\x80\x4e\x0a\xb4\x93\x35"
-                       "\x5d\x1d\x3f\x56\xf7\x2f\xbb\x90"
-                       "\x11\x16\x8f\xa2\xec\x47\xbe\xac"
-                       "\x56\x01\x26\x56\xb1\x8c\xb2\x10"
-                       "\xf9\x1a\xca\xf5\xd1\xb7\x39\x20"
-                       "\x63\xf1\x69\x20\x4f\x13\x12\x1f"
-                       "\x5b\x65\xfc\x98\xf7\xc4\x7a\xbe"
-                       "\xf7\x26\x4d\x2b\x84\x7b\x42\xad"
-                       "\xd8\x7a\x0a\xb4\xd8\x74\xbf\xc1"
-                       "\xf0\x6e\xb4\x29\xa3\xbb\xca\x46"
-                       "\x67\x70\x6a\x2d\xce\x0e\xa2\x8a"
-                       "\xa9\x87\xbf\x05\xc4\xc1\x04\xa3"
-                       "\xab\xd4\x45\x43\x8c\xb6\x02\xb0"
-                       "\x41\xc8\xfc\x44\x3d\x59\xaa\x2e"
-                       "\x44\x21\x2a\x8d\x88\x9d\x57\xf4"
-                       "\xa0\x02\x77\xb8\xa6\xa0\xe6\x75"
-                       "\x5c\x82\x65\x3e\x03\x5c\x29\x8f"
-                       "\x38\x55\xab\x33\x26\xef\x9f\x43"
-                       "\x52\xfd\x68\xaf\x36\xb4\xbb\x9a"
-                       "\x58\x09\x09\x1b\xc3\x65\x46\x46"
-                       "\x1d\xa7\x94\x18\x23\x50\x2c\xca"
-                       "\x2c\x55\x19\x97\x01\x9d\x93\x3b"
-                       "\x63\x86\xf2\x03\x67\x45\xd2\x72"
-                       "\x28\x52\x6c\xf4\xe3\x1c\xb5\x11"
-                       "\x13\xf1\xeb\x21\xc7\xd9\x56\x82"
-                       "\x2b\x82\x39\xbd\x69\x54\xed\x62"
-                       "\xc3\xe2\xde\x73\xd4\x6a\x12\xae"
-                       "\x13\x21\x7f\x4b\x5b\xfc\xbf\xe8"
-                       "\x2b\xbe\x56\xba\x68\x8b\x9a\xb1"
-                       "\x6e\xfa\xbf\x7e\x5a\x4b\xf1\xac"
-                       "\x98\x65\x85\xd1\x93\x53\xd3\x7b"
-                       "\x09\xdd\x4b\x10\x6d\x84\xb0\x13"
-                       "\x65\xbd\xcf\x52\x09\xc4\x85\xe2"
-                       "\x84\x74\x15\x65\xb7\xf7\x51\xaf"
-                       "\x55\xad\xa4\xd1\x22\x54\x70\x94"
-                       "\xa0\x1c\x90\x41\xfd\x99\xd7\x5a"
-                       "\x31\xef\xaa\x25\xd0\x7f\x4f\xea"
-                       "\x1d\x55\x42\xe5\x49\xb0\xd0\x46"
-                       "\x62\x36\x43\xb2\x82\x15\x75\x50"
-                       "\xa4\x72\xeb\x54\x27\x1f\x8a\xe4"
-                       "\x7d\xe9\x66\xc5\xf1\x53\xa4\xd1"
-                       "\x0c\xeb\xb8\xf8\xbc\xd4\xe2\xe7"
-                       "\xe1\xf8\x4b\xcb\xa9\xa1\xaf\x15"
-                       "\x83\xcb\x72\xd0\x33\x79\x00\x2d"
-                       "\x9f\xd7\xf1\x2e\x1e\x10\xe4\x45"
-                       "\xc0\x75\x3a\x39\xea\x68\xf7\x5d"
-                       "\x1b\x73\x8f\xe9\x8e\x0f\x72\x47"
-                       "\xae\x35\x0a\x31\x7a\x14\x4d\x4a"
-                       "\x6f\x47\xf7\x7e\x91\x6e\x74\x8b"
-                       "\x26\x47\xf9\xc3\xf9\xde\x70\xf5"
-                       "\x61\xab\xa9\x27\x9f\x82\xe4\x9c"
-                       "\x89\x91\x3f\x2e\x6a\xfd\xb5\x49"
-                       "\xe9\xfd\x59\x14\x36\x49\x40\x6d"
-                       "\x32\xd8\x85\x42\xf3\xa5\xdf\x0c"
-                       "\xa8\x27\xd7\x54\xe2\x63\x2f\xf2"
-                       "\x7e\x8b\x8b\xe7\xf1\x9a\x95\x35"
-                       "\x43\xdc\x3a\xe4\xb6\xf4\xd0\xdf"
-                       "\x9c\xcb\x94\xf3\x21\xa0\x77\x50"
-                       "\xe2\xc6\xc4\xc6\x5f\x09\x64\x5b"
-                       "\x92\x90\xd8\xe1\xd1\xed\x4b\x42"
-                       "\xd7\x37\xaf\x65\x3d\x11\x39\xb6"
-                       "\x24\x8a\x60\xae\xd6\x1e\xbf\x0e"
-                       "\x0d\xd7\xdc\x96\x0e\x65\x75\x4e"
-                       "\x29\x06\x9d\xa4\x51\x3a\x10\x63"
-                       "\x8f\x17\x07\xd5\x8e\x3c\xf4\x28"
-                       "\x00\x5a\x5b\x05\x19\xd8\xc0\x6c"
-                       "\xe5\x15\xe4\x9c\x9d\x71\x9d\x5e"
-                       "\x94\x29\x1a\xa7\x80\xfa\x0e\x33"
-                       "\x03\xdd\xb7\x3e\x9a\xa9\x26\x18"
-                       "\x37\xa9\x64\x08\x4d\x94\x5a\x88"
-                       "\xca\x35\xce\x81\x02\xe3\x1f\x1b"
-                       "\x89\x1a\x77\x85\xe3\x41\x6d\x32"
-                       "\x42\x19\x23\x7d\xc8\x73\xee\x25"
-                       "\x85\x0d\xf8\x31\x25\x79\x1b\x6f"
-                       "\x79\x25\xd2\xd8\xd4\x23\xfd\xf7"
-                       "\x82\x36\x6a\x0c\x46\x22\x15\xe9"
-                       "\xff\x72\x41\x91\x91\x7d\x3a\xb7"
-                       "\xdd\x65\x99\x70\xf6\x8d\x84\xf8"
-                       "\x67\x15\x20\x11\xd6\xb2\x55\x7b"
-                       "\xdb\x87\xee\xef\x55\x89\x2a\x59"
-                       "\x2b\x07\x8f\x43\x8a\x59\x3c\x01"
-                       "\x8b\x65\x54\xa1\x66\xd5\x38\xbd"
-                       "\xc6\x30\xa9\xcc\x49\xb6\xa8\x1b"
-                       "\xb8\xc0\x0e\xe3\x45\x28\xe2\xff"
-                       "\x41\x9f\x7e\x7c\xd1\xae\x9e\x25"
-                       "\x3f\x4c\x7c\x7c\xf4\xa8\x26\x4d"
-                       "\x5c\xfd\x4b\x27\x18\xf9\x61\x76"
-                       "\x48\xba\x0c\x6b\xa9\x4d\xfc\xf5"
-                       "\x3b\x35\x7e\x2f\x4a\xa9\xc2\x9a"
-                       "\xae\xab\x86\x09\x89\xc9\xc2\x40"
-                       "\x39\x2c\x81\xb3\xb8\x17\x67\xc2"
-                       "\x0d\x32\x4a\x3a\x67\x81\xd7\x1a"
-                       "\x34\x52\xc5\xdb\x0a\xf5\x63\x39"
-                       "\xea\x1f\xe1\x7c\xa1\x9e\xc1\x35"
-                       "\xe3\xb1\x18\x45\x67\xf9\x22\x38"
-                       "\x95\xd9\x34\x34\x86\xc6\x41\x94"
-                       "\x15\xf9\x5b\x41\xa6\x87\x8b\xf8"
-                       "\xd5\xe1\x1b\xe2\x5b\xf3\x86\x10"
-                       "\xff\xe6\xae\x69\x76\xbc\x0d\xb4"
-                       "\x09\x90\x0c\xa2\x65\x0c\xad\x74"
-                       "\xf5\xd7\xff\xda\xc1\xce\x85\xbe"
-                       "\x00\xa7\xff\x4d\x2f\x65\xd3\x8c"
-                       "\x86\x2d\x05\xe8\xed\x3e\x6b\x8b"
-                       "\x0f\x3d\x83\x8c\xf1\x1d\x5b\x96"
-                       "\x2e\xb1\x9c\xc2\x98\xe1\x70\xb9"
-                       "\xba\x5c\x8a\x43\xd6\x34\xa7\x2d"
-                       "\xc9\x92\xae\xf2\xa5\x7b\x05\x49"
-                       "\xa7\x33\x34\x86\xca\xe4\x96\x23"
-                       "\x76\x5b\xf2\xc6\xf1\x51\x28\x42"
-                       "\x7b\xcc\x76\x8f\xfa\xa2\xad\x31"
-                       "\xd4\xd6\x7a\x6d\x25\x25\x54\xe4"
-                       "\x3f\x50\x59\xe1\x5c\x05\xb7\x27"
-                       "\x48\xbf\x07\xec\x1b\x13\xbe\x2b"
-                       "\xa1\x57\x2b\xd5\xab\xd7\xd0\x4c"
-                       "\x1e\xcb\x71\x9b\xc5\x90\x85\xd3"
-                       "\xde\x59\xec\x71\xeb\x89\xbb\xd0"
-                       "\x09\x50\xe1\x16\x3f\xfd\x1c\x34"
-                       "\xc3\x1c\xa1\x10\x77\x53\x98\xef"
-                       "\xf2\xfd\xa5\x01\x59\xc2\x9b\x26"
-                       "\xc7\x42\xd9\x49\xda\x58\x2b\x6e"
-                       "\x9f\x53\x19\x76\x7e\xd9\xc9\x0e"
-                       "\x68\xc8\x7f\x51\x22\x42\xef\x49"
-                       "\xa4\x55\xb6\x36\xac\x09\xc7\x31"
-                       "\x88\x15\x4b\x2e\x8f\x3a\x08\xf7"
-                       "\xd8\xf7\xa8\xc5\xa9\x33\xa6\x45"
-                       "\xe4\xc4\x94\x76\xf3\x0d\x8f\x7e"
-                       "\xc8\xf6\xbc\x23\x0a\xb6\x4c\xd3"
-                       "\x6a\xcd\x36\xc2\x90\x5c\x5c\x3c"
-                       "\x65\x7b\xc2\xd6\xcc\xe6\x0d\x87"
-                       "\x73\x2e\x71\x79\x16\x06\x63\x28"
-                       "\x09\x15\xd8\x89\x38\x38\x3d\xb5"
-                       "\x42\x1c\x08\x24\xf7\x2a\xd2\x9d"
-                       "\xc8\xca\xef\xf9\x27\xd8\x07\x86"
-                       "\xf7\x43\x0b\x55\x15\x3f\x9f\x83"
-                       "\xef\xdc\x49\x9d\x2a\xc1\x54\x62"
-                       "\xbd\x9b\x66\x55\x9f\xb7\x12\xf3"
-                       "\x1b\x4d\x9d\x2a\x5c\xed\x87\x75"
-                       "\x87\x26\xec\x61\x2c\xb4\x0f\x89"
-                       "\xb0\xfb\x2e\x68\x5d\x15\xc7\x8d"
-                       "\x2e\xc0\xd9\xec\xaf\x4f\xd2\x25"
-                       "\x29\xe8\xd2\x26\x2b\x67\xe9\xfc"
-                       "\x2b\xa8\x67\x96\x12\x1f\x5b\x96"
-                       "\xc6\x14\x53\xaf\x44\xea\xd6\xe2"
-                       "\x94\x98\xe4\x12\x93\x4c\x92\xe0"
-                       "\x18\xa5\x8d\x2d\xe4\x71\x3c\x47"
-                       "\x4c\xf7\xe6\x47\x9e\xc0\x68\xdf"
-                       "\xd4\xf5\x5a\x74\xb1\x2b\x29\x03"
-                       "\x19\x07\xaf\x90\x62\x5c\x68\x98"
-                       "\x48\x16\x11\x02\x9d\xee\xb4\x9b"
-                       "\xe5\x42\x7f\x08\xfd\x16\x32\x0b"
-                       "\xd0\xb3\xfa\x2b\xb7\x99\xf9\x29"
-                       "\xcd\x20\x45\x9f\xb3\x1a\x5d\xa2"
-                       "\xaf\x4d\xe0\xbd\x42\x0d\xbc\x74"
-                       "\x99\x9c\x8e\x53\x1a\xb4\x3e\xbd"
-                       "\xa2\x9a\x2d\xf7\xf8\x39\x0f\x67"
-                       "\x63\xfc\x6b\xc0\xaf\xb3\x4b\x4f"
-                       "\x55\xc4\xcf\xa7\xc8\x04\x11\x3e"
-                       "\x14\x32\xbb\x1b\x38\x77\xd6\x7f"
-                       "\x54\x4c\xdf\x75\xf3\x07\x2d\x33"
-                       "\x9b\xa8\x20\xe1\x7b\x12\xb5\xf3"
-                       "\xef\x2f\xce\x72\xe5\x24\x60\xc1"
-                       "\x30\xe2\xab\xa1\x8e\x11\x09\xa8"
-                       "\x21\x33\x44\xfe\x7f\x35\x32\x93"
-                       "\x39\xa7\xad\x8b\x79\x06\xb2\xcb"
-                       "\x4e\xa9\x5f\xc7\xba\x74\x29\xec"
-                       "\x93\xa0\x4e\x54\x93\xc0\xbc\x55"
-                       "\x64\xf0\x48\xe5\x57\x99\xee\x75"
-                       "\xd6\x79\x0f\x66\xb7\xc6\x57\x76"
-                       "\xf7\xb7\xf3\x9c\xc5\x60\xe8\x7f"
-                       "\x83\x76\xd6\x0e\xaa\xe6\x90\x39"
-                       "\x1d\xa6\x32\x6a\x34\xe3\x55\xf8"
-                       "\x58\xa0\x58\x7d\x33\xe0\x22\x39"
-                       "\x44\x64\x87\x86\x5a\x2f\xa7\x7e"
-                       "\x0f\x38\xea\xb0\x30\xcc\x61\xa5"
-                       "\x6a\x32\xae\x1e\xf7\xe9\xd0\xa9"
-                       "\x0c\x32\x4b\xb5\x49\x28\xab\x85"
-                       "\x2f\x8e\x01\x36\x38\x52\xd0\xba"
-                       "\xd6\x02\x78\xf8\x0e\x3e\x9c\x8b"
-                       "\x6b\x45\x99\x3f\x5c\xfe\x58\xf1"
-                       "\x5c\x94\x04\xe1\xf5\x18\x6d\x51"
-                       "\xb2\x5d\x18\x20\xb6\xc2\x9a\x42"
-                       "\x1d\xb3\xab\x3c\xb6\x3a\x13\x03"
-                       "\xb2\x46\x82\x4f\xfc\x64\xbc\x4f"
-                       "\xca\xfa\x9c\xc0\xd5\xa7\xbd\x11"
-                       "\xb7\xe4\x5a\xf6\x6f\x4d\x4d\x54"
-                       "\xea\xa4\x98\x66\xd4\x22\x3b\xd3"
-                       "\x8f\x34\x47\xd9\x7c\xf4\x72\x3b"
-                       "\x4d\x02\x77\xf6\xd6\xdd\x08\x0a"
-                       "\x81\xe1\x86\x89\x3e\x56\x10\x3c"
-                       "\xba\xd7\x81\x8c\x08\xbc\x8b\xe2"
-                       "\x53\xec\xa7\x89\xee\xc8\x56\xb5"
-                       "\x36\x2c\xb2\x03\xba\x99\xdd\x7c"
-                       "\x48\xa0\xb0\xbc\x91\x33\xe9\xa8"
-                       "\xcb\xcd\xcf\x59\x5f\x1f\x15\xe2"
-                       "\x56\xf5\x4e\x01\x35\x27\x45\x77"
-                       "\x47\xc8\xbc\xcb\x7e\x39\xc1\x97"
-                       "\x28\xd3\x84\xfc\x2c\x3e\xc8\xad"
-                       "\x9c\xf8\x8a\x61\x9c\x28\xaa\xc5"
-                       "\x99\x20\x43\x85\x9d\xa5\xe2\x8b"
-                       "\xb8\xae\xeb\xd0\x32\x0d\x52\x78"
-                       "\x09\x56\x3f\xc7\xd8\x7e\x26\xfc"
-                       "\x37\xfb\x6f\x04\xfc\xfa\x92\x10"
-                       "\xac\xf8\x3e\x21\xdc\x8c\x21\x16"
-                       "\x7d\x67\x6e\xf6\xcd\xda\xb6\x98"
-                       "\x23\xab\x23\x3c\xb2\x10\xa0\x53"
-                       "\x5a\x56\x9f\xc5\xd0\xff\xbb\xe4"
-                       "\x98\x3c\x69\x1e\xdb\x38\x8f\x7e"
-                       "\x0f\xd2\x98\x88\x81\x8b\x45\x67"
-                       "\xea\x33\xf1\xeb\xe9\x97\x55\x2e"
-                       "\xd9\xaa\xeb\x5a\xec\xda\xe1\x68"
-                       "\xa8\x9d\x3c\x84\x7c\x05\x3d\x62"
-                       "\x87\x8f\x03\x21\x28\x95\x0c\x89"
-                       "\x25\x22\x4a\xb0\x93\xa9\x50\xa2"
-                       "\x2f\x57\x6e\x18\x42\x19\x54\x0c"
-                       "\x55\x67\xc6\x11\x49\xf4\x5c\xd2"
-                       "\xe9\x3d\xdd\x8b\x48\x71\x21\x00"
-                       "\xc3\x9a\x6c\x85\x74\x28\x83\x4a"
-                       "\x1b\x31\x05\xe1\x06\x92\xe7\xda"
-                       "\x85\x73\x78\x45\x20\x7f\xae\x13"
-                       "\x7c\x33\x06\x22\xf4\x83\xf9\x35"
-                       "\x3f\x6c\x71\xa8\x4e\x48\xbe\x9b"
-                       "\xce\x8a\xba\xda\xbe\x28\x08\xf7"
-                       "\xe2\x14\x8c\x71\xea\x72\xf9\x33"
-                       "\xf2\x88\x3f\xd7\xbb\x69\x6c\x29"
-                       "\x19\xdc\x84\xce\x1f\x12\x4f\xc8"
-                       "\xaf\xa5\x04\xba\x5a\xab\xb0\xd9"
-                       "\x14\x1f\x6c\x68\x98\x39\x89\x7a"
-                       "\xd9\xd8\x2f\xdf\xa8\x47\x4a\x25"
-                       "\xe2\xfb\x33\xf4\x59\x78\xe1\x68"
-                       "\x85\xcf\xfe\x59\x20\xd4\x05\x1d"
-                       "\x80\x99\xae\xbc\xca\xae\x0f\x2f"
-                       "\x65\x43\x34\x8e\x7e\xac\xd3\x93"
-                       "\x2f\xac\x6d\x14\x3d\x02\x07\x70"
-                       "\x9d\xa4\xf3\x1b\x5c\x36\xfc\x01"
-                       "\x73\x34\x85\x0c\x6c\xd6\xf1\xbd"
-                       "\x3f\xdf\xee\xf5\xd9\xba\x56\xef"
-                       "\xf4\x9b\x6b\xee\x9f\x5a\x78\x6d"
-                       "\x32\x19\xf4\xf7\xf8\x4c\x69\x0b"
-                       "\x4b\xbc\xbb\xb7\xf2\x85\xaf\x70"
-                       "\x75\x24\x6c\x54\xa7\x0e\x4d\x1d"
-                       "\x01\xbf\x08\xac\xcf\x7f\x2c\xe3"
-                       "\x14\x89\x5e\x70\x5a\x99\x92\xcd"
-                       "\x01\x84\xc8\xd2\xab\xe5\x4f\x58"
-                       "\xe7\x0f\x2f\x0e\xff\x68\xea\xfd"
-                       "\x15\xb3\x17\xe6\xb0\xe7\x85\xd8"
-                       "\x23\x2e\x05\xc7\xc9\xc4\x46\x1f"
-                       "\xe1\x9e\x49\x20\x23\x24\x4d\x7e"
-                       "\x29\x65\xff\xf4\xb6\xfd\x1a\x85"
-                       "\xc4\x16\xec\xfc\xea\x7b\xd6\x2c"
-                       "\x43\xf8\xb7\xbf\x79\xc0\x85\xcd"
-                       "\xef\xe1\x98\xd3\xa5\xf7\x90\x8c"
-                       "\xe9\x7f\x80\x6b\xd2\xac\x4c\x30"
-                       "\xa7\xc6\x61\x6c\xd2\xf9\x2c\xff"
-                       "\x30\xbc\x22\x81\x7d\x93\x12\xe4"
-                       "\x0a\xcd\xaf\xdd\xe8\xab\x0a\x1e"
-                       "\x13\xa4\x27\xc3\x5f\xf7\x4b\xbb"
-                       "\x37\x09\x4b\x91\x6f\x92\x4f\xaf"
-                       "\x52\xee\xdf\xef\x09\x6f\xf7\x5c"
-                       "\x6e\x12\x17\x72\x63\x57\xc7\xba"
-                       "\x3b\x6b\x38\x32\x73\x1b\x9c\x80"
-                       "\xc1\x7a\xc6\xcf\xcd\x35\xc0\x6b"
-                       "\x31\x1a\x6b\xe9\xd8\x2c\x29\x3f"
-                       "\x96\xfb\xb6\xcd\x13\x91\x3b\xc2"
-                       "\xd2\xa3\x31\x8d\xa4\xcd\x57\xcd"
-                       "\x13\x3d\x64\xfd\x06\xce\xe6\xdc"
-                       "\x0c\x24\x43\x31\x40\x57\xf1\x72"
-                       "\x17\xe3\x3a\x63\x6d\x35\xcf\x5d"
-                       "\x97\x40\x59\xdd\xf7\x3c\x02\xf7"
-                       "\x1c\x7e\x05\xbb\xa9\x0d\x01\xb1"
-                       "\x8e\xc0\x30\xa9\x53\x24\xc9\x89"
-                       "\x84\x6d\xaa\xd0\xcd\x91\xc2\x4d"
-                       "\x91\xb0\x89\xe2\xbf\x83\x44\xaa"
-                       "\x28\x72\x23\xa0\xc2\xad\xad\x1c"
-                       "\xfc\x3f\x09\x7a\x0b\xdc\xc5\x1b"
-                       "\x87\x13\xc6\x5b\x59\x8d\xf2\xc8"
-                       "\xaf\xdf\x11\x95",
-               .rlen = 4100,
-       },
-};
-
-/*
- * CTS (Cipher Text Stealing) mode tests
- */
-#define CTS_MODE_ENC_TEST_VECTORS 6
-#define CTS_MODE_DEC_TEST_VECTORS 6
-static struct cipher_testvec cts_mode_enc_tv_template[] = {
-       { /* from rfc3962 */
-               .klen   = 16,
-               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
-                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
-               .ilen   = 17,
-               .input  = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
-                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
-                         "\x20",
-               .rlen   = 17,
-               .result = "\xc6\x35\x35\x68\xf2\xbf\x8c\xb4"
-                         "\xd8\xa5\x80\x36\x2d\xa7\xff\x7f"
-                         "\x97",
-       }, {
-               .klen   = 16,
-               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
-                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
-               .ilen   = 31,
-               .input  = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
-                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
-                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
-                         "\x20\x47\x61\x75\x27\x73\x20",
-               .rlen   = 31,
-               .result = "\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1"
-                         "\xd4\x45\xd4\xc8\xef\xf7\xed\x22"
-                         "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
-                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5",
-       }, {
-               .klen   = 16,
-               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
-                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
-               .ilen   = 32,
-               .input  = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
-                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
-                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
-                         "\x20\x47\x61\x75\x27\x73\x20\x43",
-               .rlen   = 32,
-               .result = "\x39\x31\x25\x23\xa7\x86\x62\xd5"
-                         "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
-                         "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
-                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84",
-       }, {
-               .klen   = 16,
-               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
-                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
-               .ilen   = 47,
-               .input  = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
-                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
-                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
-                         "\x20\x47\x61\x75\x27\x73\x20\x43"
-                         "\x68\x69\x63\x6b\x65\x6e\x2c\x20"
-                         "\x70\x6c\x65\x61\x73\x65\x2c",
-               .rlen   = 47,
-               .result = "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
-                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
-                         "\xb3\xff\xfd\x94\x0c\x16\xa1\x8c"
-                         "\x1b\x55\x49\xd2\xf8\x38\x02\x9e"
-                         "\x39\x31\x25\x23\xa7\x86\x62\xd5"
-                         "\xbe\x7f\xcb\xcc\x98\xeb\xf5",
-       }, {
-               .klen   = 16,
-               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
-                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
-               .ilen   = 48,
-               .input  = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
-                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
-                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
-                         "\x20\x47\x61\x75\x27\x73\x20\x43"
-                         "\x68\x69\x63\x6b\x65\x6e\x2c\x20"
-                         "\x70\x6c\x65\x61\x73\x65\x2c\x20",
-               .rlen   = 48,
-               .result = "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
-                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
-                         "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0"
-                         "\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8"
-                         "\x39\x31\x25\x23\xa7\x86\x62\xd5"
-                         "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8",
-       }, {
-               .klen   = 16,
-               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
-                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
-               .ilen   = 64,
-               .input  = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
-                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
-                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
-                         "\x20\x47\x61\x75\x27\x73\x20\x43"
-                         "\x68\x69\x63\x6b\x65\x6e\x2c\x20"
-                         "\x70\x6c\x65\x61\x73\x65\x2c\x20"
-                         "\x61\x6e\x64\x20\x77\x6f\x6e\x74"
-                         "\x6f\x6e\x20\x73\x6f\x75\x70\x2e",
-               .rlen   = 64,
-               .result = "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
-                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
-                         "\x39\x31\x25\x23\xa7\x86\x62\xd5"
-                         "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
-                         "\x48\x07\xef\xe8\x36\xee\x89\xa5"
-                         "\x26\x73\x0d\xbc\x2f\x7b\xc8\x40"
-                         "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0"
-                         "\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8",
-       }
-};
-
-static struct cipher_testvec cts_mode_dec_tv_template[] = {
-       { /* from rfc3962 */
-               .klen   = 16,
-               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
-                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
-               .rlen   = 17,
-               .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
-                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
-                         "\x20",
-               .ilen   = 17,
-               .input  = "\xc6\x35\x35\x68\xf2\xbf\x8c\xb4"
-                         "\xd8\xa5\x80\x36\x2d\xa7\xff\x7f"
-                         "\x97",
-       }, {
-               .klen   = 16,
-               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
-                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
-               .rlen   = 31,
-               .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
-                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
-                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
-                         "\x20\x47\x61\x75\x27\x73\x20",
-               .ilen   = 31,
-               .input  = "\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1"
-                         "\xd4\x45\xd4\xc8\xef\xf7\xed\x22"
-                         "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
-                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5",
-       }, {
-               .klen   = 16,
-               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
-                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
-               .rlen   = 32,
-               .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
-                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
-                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
-                         "\x20\x47\x61\x75\x27\x73\x20\x43",
-               .ilen   = 32,
-               .input  = "\x39\x31\x25\x23\xa7\x86\x62\xd5"
-                         "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
-                         "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
-                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84",
-       }, {
-               .klen   = 16,
-               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
-                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
-               .rlen   = 47,
-               .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
-                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
-                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
-                         "\x20\x47\x61\x75\x27\x73\x20\x43"
-                         "\x68\x69\x63\x6b\x65\x6e\x2c\x20"
-                         "\x70\x6c\x65\x61\x73\x65\x2c",
-               .ilen   = 47,
-               .input  = "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
-                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
-                         "\xb3\xff\xfd\x94\x0c\x16\xa1\x8c"
-                         "\x1b\x55\x49\xd2\xf8\x38\x02\x9e"
-                         "\x39\x31\x25\x23\xa7\x86\x62\xd5"
-                         "\xbe\x7f\xcb\xcc\x98\xeb\xf5",
-       }, {
-               .klen   = 16,
-               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
-                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
-               .rlen   = 48,
-               .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
-                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
-                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
-                         "\x20\x47\x61\x75\x27\x73\x20\x43"
-                         "\x68\x69\x63\x6b\x65\x6e\x2c\x20"
-                         "\x70\x6c\x65\x61\x73\x65\x2c\x20",
-               .ilen   = 48,
-               .input  = "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
-                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
-                         "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0"
-                         "\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8"
-                         "\x39\x31\x25\x23\xa7\x86\x62\xd5"
-                         "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8",
-       }, {
-               .klen   = 16,
-               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
-                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
-               .rlen   = 64,
-               .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
-                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
-                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
-                         "\x20\x47\x61\x75\x27\x73\x20\x43"
-                         "\x68\x69\x63\x6b\x65\x6e\x2c\x20"
-                         "\x70\x6c\x65\x61\x73\x65\x2c\x20"
-                         "\x61\x6e\x64\x20\x77\x6f\x6e\x74"
-                         "\x6f\x6e\x20\x73\x6f\x75\x70\x2e",
-               .ilen   = 64,
-               .input  = "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
-                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
-                         "\x39\x31\x25\x23\xa7\x86\x62\xd5"
-                         "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
-                         "\x48\x07\xef\xe8\x36\xee\x89\xa5"
-                         "\x26\x73\x0d\xbc\x2f\x7b\xc8\x40"
-                         "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0"
-                         "\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8",
-       }
-};
-
-/*
- * Compression stuff.
- */
-#define COMP_BUF_SIZE           512
-
-struct comp_testvec {
-       int inlen, outlen;
-       char input[COMP_BUF_SIZE];
-       char output[COMP_BUF_SIZE];
-};
-
-/*
- * Deflate test vectors (null-terminated strings).
- * Params: winbits=11, Z_DEFAULT_COMPRESSION, MAX_MEM_LEVEL.
- */
-#define DEFLATE_COMP_TEST_VECTORS 2
-#define DEFLATE_DECOMP_TEST_VECTORS 2
-
-static struct comp_testvec deflate_comp_tv_template[] = {
-       {
-               .inlen  = 70,
-               .outlen = 38,
-               .input  = "Join us now and share the software "
-                       "Join us now and share the software ",
-               .output = "\xf3\xca\xcf\xcc\x53\x28\x2d\x56"
-                         "\xc8\xcb\x2f\x57\x48\xcc\x4b\x51"
-                         "\x28\xce\x48\x2c\x4a\x55\x28\xc9"
-                         "\x48\x55\x28\xce\x4f\x2b\x29\x07"
-                         "\x71\xbc\x08\x2b\x01\x00",
-       }, {
-               .inlen  = 191,
-               .outlen = 122,
-               .input  = "This document describes a compression method based on the DEFLATE"
-                       "compression algorithm.  This document defines the application of "
-                       "the DEFLATE algorithm to the IP Payload Compression Protocol.",
-               .output = "\x5d\x8d\x31\x0e\xc2\x30\x10\x04"
-                         "\xbf\xb2\x2f\xc8\x1f\x10\x04\x09"
-                         "\x89\xc2\x85\x3f\x70\xb1\x2f\xf8"
-                         "\x24\xdb\x67\xd9\x47\xc1\xef\x49"
-                         "\x68\x12\x51\xae\x76\x67\xd6\x27"
-                         "\x19\x88\x1a\xde\x85\xab\x21\xf2"
-                         "\x08\x5d\x16\x1e\x20\x04\x2d\xad"
-                         "\xf3\x18\xa2\x15\x85\x2d\x69\xc4"
-                         "\x42\x83\x23\xb6\x6c\x89\x71\x9b"
-                         "\xef\xcf\x8b\x9f\xcf\x33\xca\x2f"
-                         "\xed\x62\xa9\x4c\x80\xff\x13\xaf"
-                         "\x52\x37\xed\x0e\x52\x6b\x59\x02"
-                         "\xd9\x4e\xe8\x7a\x76\x1d\x02\x98"
-                         "\xfe\x8a\x87\x83\xa3\x4f\x56\x8a"
-                         "\xb8\x9e\x8e\x5c\x57\xd3\xa0\x79"
-                         "\xfa\x02",
-       },
-};
-
-static struct comp_testvec deflate_decomp_tv_template[] = {
-       {
-               .inlen  = 122,
-               .outlen = 191,
-               .input  = "\x5d\x8d\x31\x0e\xc2\x30\x10\x04"
-                         "\xbf\xb2\x2f\xc8\x1f\x10\x04\x09"
-                         "\x89\xc2\x85\x3f\x70\xb1\x2f\xf8"
-                         "\x24\xdb\x67\xd9\x47\xc1\xef\x49"
-                         "\x68\x12\x51\xae\x76\x67\xd6\x27"
-                         "\x19\x88\x1a\xde\x85\xab\x21\xf2"
-                         "\x08\x5d\x16\x1e\x20\x04\x2d\xad"
-                         "\xf3\x18\xa2\x15\x85\x2d\x69\xc4"
-                         "\x42\x83\x23\xb6\x6c\x89\x71\x9b"
-                         "\xef\xcf\x8b\x9f\xcf\x33\xca\x2f"
-                         "\xed\x62\xa9\x4c\x80\xff\x13\xaf"
-                         "\x52\x37\xed\x0e\x52\x6b\x59\x02"
-                         "\xd9\x4e\xe8\x7a\x76\x1d\x02\x98"
-                         "\xfe\x8a\x87\x83\xa3\x4f\x56\x8a"
-                         "\xb8\x9e\x8e\x5c\x57\xd3\xa0\x79"
-                         "\xfa\x02",
-               .output = "This document describes a compression method based on the DEFLATE"
-                       "compression algorithm.  This document defines the application of "
-                       "the DEFLATE algorithm to the IP Payload Compression Protocol.",
-       }, {
-               .inlen  = 38,
-               .outlen = 70,
-               .input  = "\xf3\xca\xcf\xcc\x53\x28\x2d\x56"
-                         "\xc8\xcb\x2f\x57\x48\xcc\x4b\x51"
-                         "\x28\xce\x48\x2c\x4a\x55\x28\xc9"
-                         "\x48\x55\x28\xce\x4f\x2b\x29\x07"
-                         "\x71\xbc\x08\x2b\x01\x00",
-               .output = "Join us now and share the software "
-                       "Join us now and share the software ",
-       },
-};
-
-/*
- * LZO test vectors (null-terminated strings).
- */
-#define LZO_COMP_TEST_VECTORS 2
-#define LZO_DECOMP_TEST_VECTORS 2
-
-static struct comp_testvec lzo_comp_tv_template[] = {
-       {
-               .inlen  = 70,
-               .outlen = 46,
-               .input  = "Join us now and share the software "
-                       "Join us now and share the software ",
-               .output = "\x00\x0d\x4a\x6f\x69\x6e\x20\x75"
-                       "\x73\x20\x6e\x6f\x77\x20\x61\x6e"
-                       "\x64\x20\x73\x68\x61\x72\x65\x20"
-                       "\x74\x68\x65\x20\x73\x6f\x66\x74"
-                       "\x77\x70\x01\x01\x4a\x6f\x69\x6e"
-                       "\x3d\x88\x00\x11\x00\x00",
-       }, {
-               .inlen  = 159,
-               .outlen = 133,
-               .input  = "This document describes a compression method based on the LZO "
-                       "compression algorithm.  This document defines the application of "
-                       "the LZO algorithm used in UBIFS.",
-               .output = "\x00\x2b\x54\x68\x69\x73\x20\x64"
-                         "\x6f\x63\x75\x6d\x65\x6e\x74\x20"
-                         "\x64\x65\x73\x63\x72\x69\x62\x65"
-                         "\x73\x20\x61\x20\x63\x6f\x6d\x70"
-                         "\x72\x65\x73\x73\x69\x6f\x6e\x20"
-                         "\x6d\x65\x74\x68\x6f\x64\x20\x62"
-                         "\x61\x73\x65\x64\x20\x6f\x6e\x20"
-                         "\x74\x68\x65\x20\x4c\x5a\x4f\x2b"
-                         "\x8c\x00\x0d\x61\x6c\x67\x6f\x72"
-                         "\x69\x74\x68\x6d\x2e\x20\x20\x54"
-                         "\x68\x69\x73\x2a\x54\x01\x02\x66"
-                         "\x69\x6e\x65\x73\x94\x06\x05\x61"
-                         "\x70\x70\x6c\x69\x63\x61\x74\x76"
-                         "\x0a\x6f\x66\x88\x02\x60\x09\x27"
-                         "\xf0\x00\x0c\x20\x75\x73\x65\x64"
-                         "\x20\x69\x6e\x20\x55\x42\x49\x46"
-                         "\x53\x2e\x11\x00\x00",
-       },
-};
-
-static struct comp_testvec lzo_decomp_tv_template[] = {
-       {
-               .inlen  = 133,
-               .outlen = 159,
-               .input  = "\x00\x2b\x54\x68\x69\x73\x20\x64"
-                         "\x6f\x63\x75\x6d\x65\x6e\x74\x20"
-                         "\x64\x65\x73\x63\x72\x69\x62\x65"
-                         "\x73\x20\x61\x20\x63\x6f\x6d\x70"
-                         "\x72\x65\x73\x73\x69\x6f\x6e\x20"
-                         "\x6d\x65\x74\x68\x6f\x64\x20\x62"
-                         "\x61\x73\x65\x64\x20\x6f\x6e\x20"
-                         "\x74\x68\x65\x20\x4c\x5a\x4f\x2b"
-                         "\x8c\x00\x0d\x61\x6c\x67\x6f\x72"
-                         "\x69\x74\x68\x6d\x2e\x20\x20\x54"
-                         "\x68\x69\x73\x2a\x54\x01\x02\x66"
-                         "\x69\x6e\x65\x73\x94\x06\x05\x61"
-                         "\x70\x70\x6c\x69\x63\x61\x74\x76"
-                         "\x0a\x6f\x66\x88\x02\x60\x09\x27"
-                         "\xf0\x00\x0c\x20\x75\x73\x65\x64"
-                         "\x20\x69\x6e\x20\x55\x42\x49\x46"
-                         "\x53\x2e\x11\x00\x00",
-               .output = "This document describes a compression method based on the LZO "
-                       "compression algorithm.  This document defines the application of "
-                       "the LZO algorithm used in UBIFS.",
-       }, {
-               .inlen  = 46,
-               .outlen = 70,
-               .input  = "\x00\x0d\x4a\x6f\x69\x6e\x20\x75"
-                         "\x73\x20\x6e\x6f\x77\x20\x61\x6e"
-                         "\x64\x20\x73\x68\x61\x72\x65\x20"
-                         "\x74\x68\x65\x20\x73\x6f\x66\x74"
-                         "\x77\x70\x01\x01\x4a\x6f\x69\x6e"
-                         "\x3d\x88\x00\x11\x00\x00",
-               .output = "Join us now and share the software "
-                       "Join us now and share the software ",
-       },
-};
-
-/*
- * Michael MIC test vectors from IEEE 802.11i
- */
-#define MICHAEL_MIC_TEST_VECTORS 6
-
-static struct hash_testvec michael_mic_tv_template[] = {
-       {
-               .key = "\x00\x00\x00\x00\x00\x00\x00\x00",
-               .ksize = 8,
-               .plaintext = zeroed_string,
-               .psize = 0,
-               .digest = "\x82\x92\x5c\x1c\xa1\xd1\x30\xb8",
-       },
-       {
-               .key = "\x82\x92\x5c\x1c\xa1\xd1\x30\xb8",
-               .ksize = 8,
-               .plaintext = "M",
-               .psize = 1,
-               .digest = "\x43\x47\x21\xca\x40\x63\x9b\x3f",
-       },
-       {
-               .key = "\x43\x47\x21\xca\x40\x63\x9b\x3f",
-               .ksize = 8,
-               .plaintext = "Mi",
-               .psize = 2,
-               .digest = "\xe8\xf9\xbe\xca\xe9\x7e\x5d\x29",
-       },
-       {
-               .key = "\xe8\xf9\xbe\xca\xe9\x7e\x5d\x29",
-               .ksize = 8,
-               .plaintext = "Mic",
-               .psize = 3,
-               .digest = "\x90\x03\x8f\xc6\xcf\x13\xc1\xdb",
-       },
-       {
-               .key = "\x90\x03\x8f\xc6\xcf\x13\xc1\xdb",
-               .ksize = 8,
-               .plaintext = "Mich",
-               .psize = 4,
-               .digest = "\xd5\x5e\x10\x05\x10\x12\x89\x86",
-       },
-       {
-               .key = "\xd5\x5e\x10\x05\x10\x12\x89\x86",
-               .ksize = 8,
-               .plaintext = "Michael",
-               .psize = 7,
-               .digest = "\x0a\x94\x2b\x12\x4e\xca\xa5\x46",
-       }
-};
-
-/*
- * CRC32C test vectors
- */
-#define CRC32C_TEST_VECTORS 14
-
-static struct hash_testvec crc32c_tv_template[] = {
-       {
-               .psize = 0,
-               .digest = "\x00\x00\x00\x00",
-       },
-       {
-               .key = "\x87\xa9\xcb\xed",
-               .ksize = 4,
-               .psize = 0,
-               .digest = "\x78\x56\x34\x12",
-       },
-       {
-               .key = "\xff\xff\xff\xff",
-               .ksize = 4,
-               .plaintext = "\x01\x02\x03\x04\x05\x06\x07\x08"
-                            "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
-                            "\x11\x12\x13\x14\x15\x16\x17\x18"
-                            "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
-                            "\x21\x22\x23\x24\x25\x26\x27\x28",
-               .psize = 40,
-               .digest = "\x7f\x15\x2c\x0e",
-       },
-       {
-               .key = "\xff\xff\xff\xff",
-               .ksize = 4,
-               .plaintext = "\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"
-                            "\x31\x32\x33\x34\x35\x36\x37\x38"
-                            "\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
-                            "\x41\x42\x43\x44\x45\x46\x47\x48"
-                            "\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50",
-               .psize = 40,
-               .digest = "\xf6\xeb\x80\xe9",
-       },
-       {
-               .key = "\xff\xff\xff\xff",
-               .ksize = 4,
-               .plaintext = "\x51\x52\x53\x54\x55\x56\x57\x58"
-                            "\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"
-                            "\x61\x62\x63\x64\x65\x66\x67\x68"
-                            "\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
-                            "\x71\x72\x73\x74\x75\x76\x77\x78",
-               .psize = 40,
-               .digest = "\xed\xbd\x74\xde",
-       },
-       {
-               .key = "\xff\xff\xff\xff",
-               .ksize = 4,
-               .plaintext = "\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"
-                            "\x81\x82\x83\x84\x85\x86\x87\x88"
-                            "\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
-                            "\x91\x92\x93\x94\x95\x96\x97\x98"
-                            "\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0",
-               .psize = 40,
-               .digest = "\x62\xc8\x79\xd5",
-       },
-       {
-               .key = "\xff\xff\xff\xff",
-               .ksize = 4,
-               .plaintext = "\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8"
-                            "\xa9\xaa\xab\xac\xad\xae\xaf\xb0"
-                            "\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8"
-                            "\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"
-                            "\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8",
-               .psize = 40,
-               .digest = "\xd0\x9a\x97\xba",
-       },
-       {
-               .key = "\xff\xff\xff\xff",
-               .ksize = 4,
-               .plaintext = "\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0"
-                            "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8"
-                            "\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
-                            "\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8"
-                            "\xe9\xea\xeb\xec\xed\xee\xef\xf0",
-               .psize = 40,
-               .digest = "\x13\xd9\x29\x2b",
-       },
-       {
-               .key = "\x80\xea\xd3\xf1",
-               .ksize = 4,
-               .plaintext = "\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"
-                            "\x31\x32\x33\x34\x35\x36\x37\x38"
-                            "\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
-                            "\x41\x42\x43\x44\x45\x46\x47\x48"
-                            "\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50",
-               .psize = 40,
-               .digest = "\x0c\xb5\xe2\xa2",
-       },
-       {
-               .key = "\xf3\x4a\x1d\x5d",
-               .ksize = 4,
-               .plaintext = "\x51\x52\x53\x54\x55\x56\x57\x58"
-                            "\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"
-                            "\x61\x62\x63\x64\x65\x66\x67\x68"
-                            "\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
-                            "\x71\x72\x73\x74\x75\x76\x77\x78",
-               .psize = 40,
-               .digest = "\xd1\x7f\xfb\xa6",
-       },
-       {
-               .key = "\x2e\x80\x04\x59",
-               .ksize = 4,
-               .plaintext = "\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"
-                            "\x81\x82\x83\x84\x85\x86\x87\x88"
-                            "\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
-                            "\x91\x92\x93\x94\x95\x96\x97\x98"
-                            "\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0",
-               .psize = 40,
-               .digest = "\x59\x33\xe6\x7a",
-       },
-       {
-               .key = "\xa6\xcc\x19\x85",
-               .ksize = 4,
-               .plaintext = "\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8"
-                            "\xa9\xaa\xab\xac\xad\xae\xaf\xb0"
-                            "\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8"
-                            "\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"
-                            "\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8",
-               .psize = 40,
-               .digest = "\xbe\x03\x01\xd2",
-       },
-       {
-               .key = "\x41\xfc\xfe\x2d",
-               .ksize = 4,
-               .plaintext = "\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0"
-                            "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8"
-                            "\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
-                            "\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8"
-                            "\xe9\xea\xeb\xec\xed\xee\xef\xf0",
-               .psize = 40,
-               .digest = "\x75\xd3\xc5\x24",
-       },
-       {
-               .key = "\xff\xff\xff\xff",
-               .ksize = 4,
-               .plaintext = "\x01\x02\x03\x04\x05\x06\x07\x08"
-                            "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
-                            "\x11\x12\x13\x14\x15\x16\x17\x18"
-                            "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
-                            "\x21\x22\x23\x24\x25\x26\x27\x28"
-                            "\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"
-                            "\x31\x32\x33\x34\x35\x36\x37\x38"
-                            "\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
-                            "\x41\x42\x43\x44\x45\x46\x47\x48"
-                            "\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
-                            "\x51\x52\x53\x54\x55\x56\x57\x58"
-                            "\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"
-                            "\x61\x62\x63\x64\x65\x66\x67\x68"
-                            "\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
-                            "\x71\x72\x73\x74\x75\x76\x77\x78"
-                            "\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"
-                            "\x81\x82\x83\x84\x85\x86\x87\x88"
-                            "\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
-                            "\x91\x92\x93\x94\x95\x96\x97\x98"
-                            "\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0"
-                            "\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8"
-                            "\xa9\xaa\xab\xac\xad\xae\xaf\xb0"
-                            "\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8"
-                            "\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"
-                            "\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8"
-                            "\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0"
-                            "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8"
-                            "\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
-                            "\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8"
-                            "\xe9\xea\xeb\xec\xed\xee\xef\xf0",
-               .psize = 240,
-               .digest = "\x75\xd3\xc5\x24",
-               .np = 2,
-               .tap = { 31, 209 }
-       },
-};
-
 /*
  * Cipher speed tests
  */
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
new file mode 100644 (file)
index 0000000..b828c6c
--- /dev/null
@@ -0,0 +1,1868 @@
+/*
+ * Algorithm testing framework and tests.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ * Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org>
+ * Copyright (c) 2007 Nokia Siemens Networks
+ * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au>
+ *
+ * This program 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.
+ *
+ */
+
+#include <crypto/hash.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include "internal.h"
+#include "testmgr.h"
+
+/*
+ * Need slab memory for testing (size in number of pages).
+ */
+#define XBUFSIZE       8
+
+/*
+ * Indexes into the xbuf to simulate cross-page access.
+ */
+#define IDX1           32
+#define IDX2           32400
+#define IDX3           1
+#define IDX4           8193
+#define IDX5           22222
+#define IDX6           17101
+#define IDX7           27333
+#define IDX8           3000
+
+/*
+* Used by test_cipher()
+*/
+#define ENCRYPT 1
+#define DECRYPT 0
+
+struct tcrypt_result {
+       struct completion completion;
+       int err;
+};
+
+struct aead_test_suite {
+       struct {
+               struct aead_testvec *vecs;
+               unsigned int count;
+       } enc, dec;
+};
+
+struct cipher_test_suite {
+       struct {
+               struct cipher_testvec *vecs;
+               unsigned int count;
+       } enc, dec;
+};
+
+struct comp_test_suite {
+       struct {
+               struct comp_testvec *vecs;
+               unsigned int count;
+       } comp, decomp;
+};
+
+struct hash_test_suite {
+       struct hash_testvec *vecs;
+       unsigned int count;
+};
+
+struct alg_test_desc {
+       const char *alg;
+       int (*test)(const struct alg_test_desc *desc, const char *driver,
+                   u32 type, u32 mask);
+
+       union {
+               struct aead_test_suite aead;
+               struct cipher_test_suite cipher;
+               struct comp_test_suite comp;
+               struct hash_test_suite hash;
+       } suite;
+};
+
+static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 };
+
+static char *xbuf[XBUFSIZE];
+static char *axbuf[XBUFSIZE];
+
+static void hexdump(unsigned char *buf, unsigned int len)
+{
+       print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET,
+                       16, 1,
+                       buf, len, false);
+}
+
+static void tcrypt_complete(struct crypto_async_request *req, int err)
+{
+       struct tcrypt_result *res = req->data;
+
+       if (err == -EINPROGRESS)
+               return;
+
+       res->err = err;
+       complete(&res->completion);
+}
+
+static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
+                    unsigned int tcount)
+{
+       const char *algo = crypto_tfm_alg_driver_name(crypto_ahash_tfm(tfm));
+       unsigned int i, j, k, temp;
+       struct scatterlist sg[8];
+       char result[64];
+       struct ahash_request *req;
+       struct tcrypt_result tresult;
+       int ret;
+       void *hash_buff;
+
+       init_completion(&tresult.completion);
+
+       req = ahash_request_alloc(tfm, GFP_KERNEL);
+       if (!req) {
+               printk(KERN_ERR "alg: hash: Failed to allocate request for "
+                      "%s\n", algo);
+               ret = -ENOMEM;
+               goto out_noreq;
+       }
+       ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+                                  tcrypt_complete, &tresult);
+
+       for (i = 0; i < tcount; i++) {
+               memset(result, 0, 64);
+
+               hash_buff = xbuf[0];
+
+               memcpy(hash_buff, template[i].plaintext, template[i].psize);
+               sg_init_one(&sg[0], hash_buff, template[i].psize);
+
+               if (template[i].ksize) {
+                       crypto_ahash_clear_flags(tfm, ~0);
+                       ret = crypto_ahash_setkey(tfm, template[i].key,
+                                                 template[i].ksize);
+                       if (ret) {
+                               printk(KERN_ERR "alg: hash: setkey failed on "
+                                      "test %d for %s: ret=%d\n", i + 1, algo,
+                                      -ret);
+                               goto out;
+                       }
+               }
+
+               ahash_request_set_crypt(req, sg, result, template[i].psize);
+               ret = crypto_ahash_digest(req);
+               switch (ret) {
+               case 0:
+                       break;
+               case -EINPROGRESS:
+               case -EBUSY:
+                       ret = wait_for_completion_interruptible(
+                               &tresult.completion);
+                       if (!ret && !(ret = tresult.err)) {
+                               INIT_COMPLETION(tresult.completion);
+                               break;
+                       }
+                       /* fall through */
+               default:
+                       printk(KERN_ERR "alg: hash: digest failed on test %d "
+                              "for %s: ret=%d\n", i + 1, algo, -ret);
+                       goto out;
+               }
+
+               if (memcmp(result, template[i].digest,
+                          crypto_ahash_digestsize(tfm))) {
+                       printk(KERN_ERR "alg: hash: Test %d failed for %s\n",
+                              i + 1, algo);
+                       hexdump(result, crypto_ahash_digestsize(tfm));
+                       ret = -EINVAL;
+                       goto out;
+               }
+       }
+
+       j = 0;
+       for (i = 0; i < tcount; i++) {
+               if (template[i].np) {
+                       j++;
+                       memset(result, 0, 64);
+
+                       temp = 0;
+                       sg_init_table(sg, template[i].np);
+                       for (k = 0; k < template[i].np; k++) {
+                               sg_set_buf(&sg[k],
+                                          memcpy(xbuf[IDX[k] >> PAGE_SHIFT] +
+                                                 offset_in_page(IDX[k]),
+                                                 template[i].plaintext + temp,
+                                                 template[i].tap[k]),
+                                          template[i].tap[k]);
+                               temp += template[i].tap[k];
+                       }
+
+                       if (template[i].ksize) {
+                               crypto_ahash_clear_flags(tfm, ~0);
+                               ret = crypto_ahash_setkey(tfm, template[i].key,
+                                                         template[i].ksize);
+
+                               if (ret) {
+                                       printk(KERN_ERR "alg: hash: setkey "
+                                              "failed on chunking test %d "
+                                              "for %s: ret=%d\n", j, algo,
+                                              -ret);
+                                       goto out;
+                               }
+                       }
+
+                       ahash_request_set_crypt(req, sg, result,
+                                               template[i].psize);
+                       ret = crypto_ahash_digest(req);
+                       switch (ret) {
+                       case 0:
+                               break;
+                       case -EINPROGRESS:
+                       case -EBUSY:
+                               ret = wait_for_completion_interruptible(
+                                       &tresult.completion);
+                               if (!ret && !(ret = tresult.err)) {
+                                       INIT_COMPLETION(tresult.completion);
+                                       break;
+                               }
+                               /* fall through */
+                       default:
+                               printk(KERN_ERR "alg: hash: digest failed "
+                                      "on chunking test %d for %s: "
+                                      "ret=%d\n", j, algo, -ret);
+                               goto out;
+                       }
+
+                       if (memcmp(result, template[i].digest,
+                                  crypto_ahash_digestsize(tfm))) {
+                               printk(KERN_ERR "alg: hash: Chunking test %d "
+                                      "failed for %s\n", j, algo);
+                               hexdump(result, crypto_ahash_digestsize(tfm));
+                               ret = -EINVAL;
+                               goto out;
+                       }
+               }
+       }
+
+       ret = 0;
+
+out:
+       ahash_request_free(req);
+out_noreq:
+       return ret;
+}
+
+static int test_aead(struct crypto_aead *tfm, int enc,
+                    struct aead_testvec *template, unsigned int tcount)
+{
+       const char *algo = crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm));
+       unsigned int i, j, k, n, temp;
+       int ret = 0;
+       char *q;
+       char *key;
+       struct aead_request *req;
+       struct scatterlist sg[8];
+       struct scatterlist asg[8];
+       const char *e;
+       struct tcrypt_result result;
+       unsigned int authsize;
+       void *input;
+       void *assoc;
+       char iv[MAX_IVLEN];
+
+       if (enc == ENCRYPT)
+               e = "encryption";
+       else
+               e = "decryption";
+
+       init_completion(&result.completion);
+
+       req = aead_request_alloc(tfm, GFP_KERNEL);
+       if (!req) {
+               printk(KERN_ERR "alg: aead: Failed to allocate request for "
+                      "%s\n", algo);
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+                                 tcrypt_complete, &result);
+
+       for (i = 0, j = 0; i < tcount; i++) {
+               if (!template[i].np) {
+                       j++;
+
+                       /* some tepmplates have no input data but they will
+                        * touch input
+                        */
+                       input = xbuf[0];
+                       assoc = axbuf[0];
+
+                       memcpy(input, template[i].input, template[i].ilen);
+                       memcpy(assoc, template[i].assoc, template[i].alen);
+                       if (template[i].iv)
+                               memcpy(iv, template[i].iv, MAX_IVLEN);
+                       else
+                               memset(iv, 0, MAX_IVLEN);
+
+                       crypto_aead_clear_flags(tfm, ~0);
+                       if (template[i].wk)
+                               crypto_aead_set_flags(
+                                       tfm, CRYPTO_TFM_REQ_WEAK_KEY);
+
+                       key = template[i].key;
+
+                       ret = crypto_aead_setkey(tfm, key,
+                                                template[i].klen);
+                       if (!ret == template[i].fail) {
+                               printk(KERN_ERR "alg: aead: setkey failed on "
+                                      "test %d for %s: flags=%x\n", j, algo,
+                                      crypto_aead_get_flags(tfm));
+                               goto out;
+                       } else if (ret)
+                               continue;
+
+                       authsize = abs(template[i].rlen - template[i].ilen);
+                       ret = crypto_aead_setauthsize(tfm, authsize);
+                       if (ret) {
+                               printk(KERN_ERR "alg: aead: Failed to set "
+                                      "authsize to %u on test %d for %s\n",
+                                      authsize, j, algo);
+                               goto out;
+                       }
+
+                       sg_init_one(&sg[0], input,
+                                   template[i].ilen + (enc ? authsize : 0));
+
+                       sg_init_one(&asg[0], assoc, template[i].alen);
+
+                       aead_request_set_crypt(req, sg, sg,
+                                              template[i].ilen, iv);
+
+                       aead_request_set_assoc(req, asg, template[i].alen);
+
+                       ret = enc ?
+                               crypto_aead_encrypt(req) :
+                               crypto_aead_decrypt(req);
+
+                       switch (ret) {
+                       case 0:
+                               break;
+                       case -EINPROGRESS:
+                       case -EBUSY:
+                               ret = wait_for_completion_interruptible(
+                                       &result.completion);
+                               if (!ret && !(ret = result.err)) {
+                                       INIT_COMPLETION(result.completion);
+                                       break;
+                               }
+                               /* fall through */
+                       default:
+                               printk(KERN_ERR "alg: aead: %s failed on test "
+                                      "%d for %s: ret=%d\n", e, j, algo, -ret);
+                               goto out;
+                       }
+
+                       q = input;
+                       if (memcmp(q, template[i].result, template[i].rlen)) {
+                               printk(KERN_ERR "alg: aead: Test %d failed on "
+                                      "%s for %s\n", j, e, algo);
+                               hexdump(q, template[i].rlen);
+                               ret = -EINVAL;
+                               goto out;
+                       }
+               }
+       }
+
+       for (i = 0, j = 0; i < tcount; i++) {
+               if (template[i].np) {
+                       j++;
+
+                       if (template[i].iv)
+                               memcpy(iv, template[i].iv, MAX_IVLEN);
+                       else
+                               memset(iv, 0, MAX_IVLEN);
+
+                       crypto_aead_clear_flags(tfm, ~0);
+                       if (template[i].wk)
+                               crypto_aead_set_flags(
+                                       tfm, CRYPTO_TFM_REQ_WEAK_KEY);
+                       key = template[i].key;
+
+                       ret = crypto_aead_setkey(tfm, key, template[i].klen);
+                       if (!ret == template[i].fail) {
+                               printk(KERN_ERR "alg: aead: setkey failed on "
+                                      "chunk test %d for %s: flags=%x\n", j,
+                                      algo, crypto_aead_get_flags(tfm));
+                               goto out;
+                       } else if (ret)
+                               continue;
+
+                       authsize = abs(template[i].rlen - template[i].ilen);
+
+                       ret = -EINVAL;
+                       sg_init_table(sg, template[i].np);
+                       for (k = 0, temp = 0; k < template[i].np; k++) {
+                               if (WARN_ON(offset_in_page(IDX[k]) +
+                                           template[i].tap[k] > PAGE_SIZE))
+                                       goto out;
+
+                               q = xbuf[IDX[k] >> PAGE_SHIFT] +
+                                   offset_in_page(IDX[k]);
+
+                               memcpy(q, template[i].input + temp,
+                                      template[i].tap[k]);
+
+                               n = template[i].tap[k];
+                               if (k == template[i].np - 1 && enc)
+                                       n += authsize;
+                               if (offset_in_page(q) + n < PAGE_SIZE)
+                                       q[n] = 0;
+
+                               sg_set_buf(&sg[k], q, template[i].tap[k]);
+                               temp += template[i].tap[k];
+                       }
+
+                       ret = crypto_aead_setauthsize(tfm, authsize);
+                       if (ret) {
+                               printk(KERN_ERR "alg: aead: Failed to set "
+                                      "authsize to %u on chunk test %d for "
+                                      "%s\n", authsize, j, algo);
+                               goto out;
+                       }
+
+                       if (enc) {
+                               if (WARN_ON(sg[k - 1].offset +
+                                           sg[k - 1].length + authsize >
+                                           PAGE_SIZE)) {
+                                       ret = -EINVAL;
+                                       goto out;
+                               }
+
+                               sg[k - 1].length += authsize;
+                       }
+
+                       sg_init_table(asg, template[i].anp);
+                       for (k = 0, temp = 0; k < template[i].anp; k++) {
+                               sg_set_buf(&asg[k],
+                                          memcpy(axbuf[IDX[k] >> PAGE_SHIFT] +
+                                                 offset_in_page(IDX[k]),
+                                                 template[i].assoc + temp,
+                                                 template[i].atap[k]),
+                                          template[i].atap[k]);
+                               temp += template[i].atap[k];
+                       }
+
+                       aead_request_set_crypt(req, sg, sg,
+                                              template[i].ilen,
+                                              iv);
+
+                       aead_request_set_assoc(req, asg, template[i].alen);
+
+                       ret = enc ?
+                               crypto_aead_encrypt(req) :
+                               crypto_aead_decrypt(req);
+
+                       switch (ret) {
+                       case 0:
+                               break;
+                       case -EINPROGRESS:
+                       case -EBUSY:
+                               ret = wait_for_completion_interruptible(
+                                       &result.completion);
+                               if (!ret && !(ret = result.err)) {
+                                       INIT_COMPLETION(result.completion);
+                                       break;
+                               }
+                               /* fall through */
+                       default:
+                               printk(KERN_ERR "alg: aead: %s failed on "
+                                      "chunk test %d for %s: ret=%d\n", e, j,
+                                      algo, -ret);
+                               goto out;
+                       }
+
+                       ret = -EINVAL;
+                       for (k = 0, temp = 0; k < template[i].np; k++) {
+                               q = xbuf[IDX[k] >> PAGE_SHIFT] +
+                                   offset_in_page(IDX[k]);
+
+                               n = template[i].tap[k];
+                               if (k == template[i].np - 1)
+                                       n += enc ? authsize : -authsize;
+
+                               if (memcmp(q, template[i].result + temp, n)) {
+                                       printk(KERN_ERR "alg: aead: Chunk "
+                                              "test %d failed on %s at page "
+                                              "%u for %s\n", j, e, k, algo);
+                                       hexdump(q, n);
+                                       goto out;
+                               }
+
+                               q += n;
+                               if (k == template[i].np - 1 && !enc) {
+                                       if (memcmp(q, template[i].input +
+                                                     temp + n, authsize))
+                                               n = authsize;
+                                       else
+                                               n = 0;
+                               } else {
+                                       for (n = 0; offset_in_page(q + n) &&
+                                                   q[n]; n++)
+                                               ;
+                               }
+                               if (n) {
+                                       printk(KERN_ERR "alg: aead: Result "
+                                              "buffer corruption in chunk "
+                                              "test %d on %s at page %u for "
+                                              "%s: %u bytes:\n", j, e, k,
+                                              algo, n);
+                                       hexdump(q, n);
+                                       goto out;
+                               }
+
+                               temp += template[i].tap[k];
+                       }
+               }
+       }
+
+       ret = 0;
+
+out:
+       aead_request_free(req);
+       return ret;
+}
+
+static int test_cipher(struct crypto_cipher *tfm, int enc,
+                      struct cipher_testvec *template, unsigned int tcount)
+{
+       const char *algo = crypto_tfm_alg_driver_name(crypto_cipher_tfm(tfm));
+       unsigned int i, j, k;
+       int ret;
+       char *q;
+       const char *e;
+       void *data;
+
+       if (enc == ENCRYPT)
+               e = "encryption";
+       else
+               e = "decryption";
+
+       j = 0;
+       for (i = 0; i < tcount; i++) {
+               if (template[i].np)
+                       continue;
+
+               j++;
+
+               data = xbuf[0];
+               memcpy(data, template[i].input, template[i].ilen);
+
+               crypto_cipher_clear_flags(tfm, ~0);
+               if (template[i].wk)
+                       crypto_cipher_set_flags(tfm, CRYPTO_TFM_REQ_WEAK_KEY);
+
+               ret = crypto_cipher_setkey(tfm, template[i].key,
+                                          template[i].klen);
+               if (!ret == template[i].fail) {
+                       printk(KERN_ERR "alg: cipher: setkey failed "
+                              "on test %d for %s: flags=%x\n", j,
+                              algo, crypto_cipher_get_flags(tfm));
+                       goto out;
+               } else if (ret)
+                       continue;
+
+               for (k = 0; k < template[i].ilen;
+                    k += crypto_cipher_blocksize(tfm)) {
+                       if (enc)
+                               crypto_cipher_encrypt_one(tfm, data + k,
+                                                         data + k);
+                       else
+                               crypto_cipher_decrypt_one(tfm, data + k,
+                                                         data + k);
+               }
+
+               q = data;
+               if (memcmp(q, template[i].result, template[i].rlen)) {
+                       printk(KERN_ERR "alg: cipher: Test %d failed "
+                              "on %s for %s\n", j, e, algo);
+                       hexdump(q, template[i].rlen);
+                       ret = -EINVAL;
+                       goto out;
+               }
+       }
+
+       ret = 0;
+
+out:
+       return ret;
+}
+
+static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
+                        struct cipher_testvec *template, unsigned int tcount)
+{
+       const char *algo =
+               crypto_tfm_alg_driver_name(crypto_ablkcipher_tfm(tfm));
+       unsigned int i, j, k, n, temp;
+       int ret;
+       char *q;
+       struct ablkcipher_request *req;
+       struct scatterlist sg[8];
+       const char *e;
+       struct tcrypt_result result;
+       void *data;
+       char iv[MAX_IVLEN];
+
+       if (enc == ENCRYPT)
+               e = "encryption";
+       else
+               e = "decryption";
+
+       init_completion(&result.completion);
+
+       req = ablkcipher_request_alloc(tfm, GFP_KERNEL);
+       if (!req) {
+               printk(KERN_ERR "alg: skcipher: Failed to allocate request "
+                      "for %s\n", algo);
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+                                       tcrypt_complete, &result);
+
+       j = 0;
+       for (i = 0; i < tcount; i++) {
+               if (template[i].iv)
+                       memcpy(iv, template[i].iv, MAX_IVLEN);
+               else
+                       memset(iv, 0, MAX_IVLEN);
+
+               if (!(template[i].np)) {
+                       j++;
+
+                       data = xbuf[0];
+                       memcpy(data, template[i].input, template[i].ilen);
+
+                       crypto_ablkcipher_clear_flags(tfm, ~0);
+                       if (template[i].wk)
+                               crypto_ablkcipher_set_flags(
+                                       tfm, CRYPTO_TFM_REQ_WEAK_KEY);
+
+                       ret = crypto_ablkcipher_setkey(tfm, template[i].key,
+                                                      template[i].klen);
+                       if (!ret == template[i].fail) {
+                               printk(KERN_ERR "alg: skcipher: setkey failed "
+                                      "on test %d for %s: flags=%x\n", j,
+                                      algo, crypto_ablkcipher_get_flags(tfm));
+                               goto out;
+                       } else if (ret)
+                               continue;
+
+                       sg_init_one(&sg[0], data, template[i].ilen);
+
+                       ablkcipher_request_set_crypt(req, sg, sg,
+                                                    template[i].ilen, iv);
+                       ret = enc ?
+                               crypto_ablkcipher_encrypt(req) :
+                               crypto_ablkcipher_decrypt(req);
+
+                       switch (ret) {
+                       case 0:
+                               break;
+                       case -EINPROGRESS:
+                       case -EBUSY:
+                               ret = wait_for_completion_interruptible(
+                                       &result.completion);
+                               if (!ret && !((ret = result.err))) {
+                                       INIT_COMPLETION(result.completion);
+                                       break;
+                               }
+                               /* fall through */
+                       default:
+                               printk(KERN_ERR "alg: skcipher: %s failed on "
+                                      "test %d for %s: ret=%d\n", e, j, algo,
+                                      -ret);
+                               goto out;
+                       }
+
+                       q = data;
+                       if (memcmp(q, template[i].result, template[i].rlen)) {
+                               printk(KERN_ERR "alg: skcipher: Test %d "
+                                      "failed on %s for %s\n", j, e, algo);
+                               hexdump(q, template[i].rlen);
+                               ret = -EINVAL;
+                               goto out;
+                       }
+               }
+       }
+
+       j = 0;
+       for (i = 0; i < tcount; i++) {
+
+               if (template[i].iv)
+                       memcpy(iv, template[i].iv, MAX_IVLEN);
+               else
+                       memset(iv, 0, MAX_IVLEN);
+
+               if (template[i].np) {
+                       j++;
+
+                       crypto_ablkcipher_clear_flags(tfm, ~0);
+                       if (template[i].wk)
+                               crypto_ablkcipher_set_flags(
+                                       tfm, CRYPTO_TFM_REQ_WEAK_KEY);
+
+                       ret = crypto_ablkcipher_setkey(tfm, template[i].key,
+                                                      template[i].klen);
+                       if (!ret == template[i].fail) {
+                               printk(KERN_ERR "alg: skcipher: setkey failed "
+                                      "on chunk test %d for %s: flags=%x\n",
+                                      j, algo,
+                                      crypto_ablkcipher_get_flags(tfm));
+                               goto out;
+                       } else if (ret)
+                               continue;
+
+                       temp = 0;
+                       ret = -EINVAL;
+                       sg_init_table(sg, template[i].np);
+                       for (k = 0; k < template[i].np; k++) {
+                               if (WARN_ON(offset_in_page(IDX[k]) +
+                                           template[i].tap[k] > PAGE_SIZE))
+                                       goto out;
+
+                               q = xbuf[IDX[k] >> PAGE_SHIFT] +
+                                   offset_in_page(IDX[k]);
+
+                               memcpy(q, template[i].input + temp,
+                                      template[i].tap[k]);
+
+                               if (offset_in_page(q) + template[i].tap[k] <
+                                   PAGE_SIZE)
+                                       q[template[i].tap[k]] = 0;
+
+                               sg_set_buf(&sg[k], q, template[i].tap[k]);
+
+                               temp += template[i].tap[k];
+                       }
+
+                       ablkcipher_request_set_crypt(req, sg, sg,
+                                       template[i].ilen, iv);
+
+                       ret = enc ?
+                               crypto_ablkcipher_encrypt(req) :
+                               crypto_ablkcipher_decrypt(req);
+
+                       switch (ret) {
+                       case 0:
+                               break;
+                       case -EINPROGRESS:
+                       case -EBUSY:
+                               ret = wait_for_completion_interruptible(
+                                       &result.completion);
+                               if (!ret && !((ret = result.err))) {
+                                       INIT_COMPLETION(result.completion);
+                                       break;
+                               }
+                               /* fall through */
+                       default:
+                               printk(KERN_ERR "alg: skcipher: %s failed on "
+                                      "chunk test %d for %s: ret=%d\n", e, j,
+                                      algo, -ret);
+                               goto out;
+                       }
+
+                       temp = 0;
+                       ret = -EINVAL;
+                       for (k = 0; k < template[i].np; k++) {
+                               q = xbuf[IDX[k] >> PAGE_SHIFT] +
+                                   offset_in_page(IDX[k]);
+
+                               if (memcmp(q, template[i].result + temp,
+                                          template[i].tap[k])) {
+                                       printk(KERN_ERR "alg: skcipher: Chunk "
+                                              "test %d failed on %s at page "
+                                              "%u for %s\n", j, e, k, algo);
+                                       hexdump(q, template[i].tap[k]);
+                                       goto out;
+                               }
+
+                               q += template[i].tap[k];
+                               for (n = 0; offset_in_page(q + n) && q[n]; n++)
+                                       ;
+                               if (n) {
+                                       printk(KERN_ERR "alg: skcipher: "
+                                              "Result buffer corruption in "
+                                              "chunk test %d on %s at page "
+                                              "%u for %s: %u bytes:\n", j, e,
+                                              k, algo, n);
+                                       hexdump(q, n);
+                                       goto out;
+                               }
+                               temp += template[i].tap[k];
+                       }
+               }
+       }
+
+       ret = 0;
+
+out:
+       ablkcipher_request_free(req);
+       return ret;
+}
+
+static int test_comp(struct crypto_comp *tfm, struct comp_testvec *ctemplate,
+                    struct comp_testvec *dtemplate, int ctcount, int dtcount)
+{
+       const char *algo = crypto_tfm_alg_driver_name(crypto_comp_tfm(tfm));
+       unsigned int i;
+       char result[COMP_BUF_SIZE];
+       int ret;
+
+       for (i = 0; i < ctcount; i++) {
+               int ilen, dlen = COMP_BUF_SIZE;
+
+               memset(result, 0, sizeof (result));
+
+               ilen = ctemplate[i].inlen;
+               ret = crypto_comp_compress(tfm, ctemplate[i].input,
+                                          ilen, result, &dlen);
+               if (ret) {
+                       printk(KERN_ERR "alg: comp: compression failed "
+                              "on test %d for %s: ret=%d\n", i + 1, algo,
+                              -ret);
+                       goto out;
+               }
+
+               if (memcmp(result, ctemplate[i].output, dlen)) {
+                       printk(KERN_ERR "alg: comp: Compression test %d "
+                              "failed for %s\n", i + 1, algo);
+                       hexdump(result, dlen);
+                       ret = -EINVAL;
+                       goto out;
+               }
+       }
+
+       for (i = 0; i < dtcount; i++) {
+               int ilen, ret, dlen = COMP_BUF_SIZE;
+
+               memset(result, 0, sizeof (result));
+
+               ilen = dtemplate[i].inlen;
+               ret = crypto_comp_decompress(tfm, dtemplate[i].input,
+                                            ilen, result, &dlen);
+               if (ret) {
+                       printk(KERN_ERR "alg: comp: decompression failed "
+                              "on test %d for %s: ret=%d\n", i + 1, algo,
+                              -ret);
+                       goto out;
+               }
+
+               if (memcmp(result, dtemplate[i].output, dlen)) {
+                       printk(KERN_ERR "alg: comp: Decompression test %d "
+                              "failed for %s\n", i + 1, algo);
+                       hexdump(result, dlen);
+                       ret = -EINVAL;
+                       goto out;
+               }
+       }
+
+       ret = 0;
+
+out:
+       return ret;
+}
+
+static int alg_test_aead(const struct alg_test_desc *desc, const char *driver,
+                        u32 type, u32 mask)
+{
+       struct crypto_aead *tfm;
+       int err = 0;
+
+       tfm = crypto_alloc_aead(driver, type, mask);
+       if (IS_ERR(tfm)) {
+               printk(KERN_ERR "alg: aead: Failed to load transform for %s: "
+                      "%ld\n", driver, PTR_ERR(tfm));
+               return PTR_ERR(tfm);
+       }
+
+       if (desc->suite.aead.enc.vecs) {
+               err = test_aead(tfm, ENCRYPT, desc->suite.aead.enc.vecs,
+                               desc->suite.aead.enc.count);
+               if (err)
+                       goto out;
+       }
+
+       if (!err && desc->suite.aead.dec.vecs)
+               err = test_aead(tfm, DECRYPT, desc->suite.aead.dec.vecs,
+                               desc->suite.aead.dec.count);
+
+out:
+       crypto_free_aead(tfm);
+       return err;
+}
+
+static int alg_test_cipher(const struct alg_test_desc *desc,
+                          const char *driver, u32 type, u32 mask)
+{
+       struct crypto_cipher *tfm;
+       int err = 0;
+
+       tfm = crypto_alloc_cipher(driver, type, mask);
+       if (IS_ERR(tfm)) {
+               printk(KERN_ERR "alg: cipher: Failed to load transform for "
+                      "%s: %ld\n", driver, PTR_ERR(tfm));
+               return PTR_ERR(tfm);
+       }
+
+       if (desc->suite.cipher.enc.vecs) {
+               err = test_cipher(tfm, ENCRYPT, desc->suite.cipher.enc.vecs,
+                                 desc->suite.cipher.enc.count);
+               if (err)
+                       goto out;
+       }
+
+       if (desc->suite.cipher.dec.vecs)
+               err = test_cipher(tfm, DECRYPT, desc->suite.cipher.dec.vecs,
+                                 desc->suite.cipher.dec.count);
+
+out:
+       crypto_free_cipher(tfm);
+       return err;
+}
+
+static int alg_test_skcipher(const struct alg_test_desc *desc,
+                            const char *driver, u32 type, u32 mask)
+{
+       struct crypto_ablkcipher *tfm;
+       int err = 0;
+
+       tfm = crypto_alloc_ablkcipher(driver, type, mask);
+       if (IS_ERR(tfm)) {
+               printk(KERN_ERR "alg: skcipher: Failed to load transform for "
+                      "%s: %ld\n", driver, PTR_ERR(tfm));
+               return PTR_ERR(tfm);
+       }
+
+       if (desc->suite.cipher.enc.vecs) {
+               err = test_skcipher(tfm, ENCRYPT, desc->suite.cipher.enc.vecs,
+                                   desc->suite.cipher.enc.count);
+               if (err)
+                       goto out;
+       }
+
+       if (desc->suite.cipher.dec.vecs)
+               err = test_skcipher(tfm, DECRYPT, desc->suite.cipher.dec.vecs,
+                                   desc->suite.cipher.dec.count);
+
+out:
+       crypto_free_ablkcipher(tfm);
+       return err;
+}
+
+static int alg_test_comp(const struct alg_test_desc *desc, const char *driver,
+                        u32 type, u32 mask)
+{
+       struct crypto_comp *tfm;
+       int err;
+
+       tfm = crypto_alloc_comp(driver, type, mask);
+       if (IS_ERR(tfm)) {
+               printk(KERN_ERR "alg: comp: Failed to load transform for %s: "
+                      "%ld\n", driver, PTR_ERR(tfm));
+               return PTR_ERR(tfm);
+       }
+
+       err = test_comp(tfm, desc->suite.comp.comp.vecs,
+                       desc->suite.comp.decomp.vecs,
+                       desc->suite.comp.comp.count,
+                       desc->suite.comp.decomp.count);
+
+       crypto_free_comp(tfm);
+       return err;
+}
+
+static int alg_test_hash(const struct alg_test_desc *desc, const char *driver,
+                        u32 type, u32 mask)
+{
+       struct crypto_ahash *tfm;
+       int err;
+
+       tfm = crypto_alloc_ahash(driver, type, mask);
+       if (IS_ERR(tfm)) {
+               printk(KERN_ERR "alg: hash: Failed to load transform for %s: "
+                      "%ld\n", driver, PTR_ERR(tfm));
+               return PTR_ERR(tfm);
+       }
+
+       err = test_hash(tfm, desc->suite.hash.vecs, desc->suite.hash.count);
+
+       crypto_free_ahash(tfm);
+       return err;
+}
+
+/* Please keep this list sorted by algorithm name. */
+static const struct alg_test_desc alg_test_descs[] = {
+       {
+               .alg = "cbc(aes)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = aes_cbc_enc_tv_template,
+                                       .count = AES_CBC_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = aes_cbc_dec_tv_template,
+                                       .count = AES_CBC_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "cbc(anubis)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = anubis_cbc_enc_tv_template,
+                                       .count = ANUBIS_CBC_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = anubis_cbc_dec_tv_template,
+                                       .count = ANUBIS_CBC_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "cbc(blowfish)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = bf_cbc_enc_tv_template,
+                                       .count = BF_CBC_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = bf_cbc_dec_tv_template,
+                                       .count = BF_CBC_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "cbc(camellia)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = camellia_cbc_enc_tv_template,
+                                       .count = CAMELLIA_CBC_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = camellia_cbc_dec_tv_template,
+                                       .count = CAMELLIA_CBC_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "cbc(des)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = des_cbc_enc_tv_template,
+                                       .count = DES_CBC_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = des_cbc_dec_tv_template,
+                                       .count = DES_CBC_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "cbc(des3_ede)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = des3_ede_cbc_enc_tv_template,
+                                       .count = DES3_EDE_CBC_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = des3_ede_cbc_dec_tv_template,
+                                       .count = DES3_EDE_CBC_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "cbc(twofish)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = tf_cbc_enc_tv_template,
+                                       .count = TF_CBC_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = tf_cbc_dec_tv_template,
+                                       .count = TF_CBC_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ccm(aes)",
+               .test = alg_test_aead,
+               .suite = {
+                       .aead = {
+                               .enc = {
+                                       .vecs = aes_ccm_enc_tv_template,
+                                       .count = AES_CCM_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = aes_ccm_dec_tv_template,
+                                       .count = AES_CCM_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "crc32c",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = crc32c_tv_template,
+                               .count = CRC32C_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "cts(cbc(aes))",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = cts_mode_enc_tv_template,
+                                       .count = CTS_MODE_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = cts_mode_dec_tv_template,
+                                       .count = CTS_MODE_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "deflate",
+               .test = alg_test_comp,
+               .suite = {
+                       .comp = {
+                               .comp = {
+                                       .vecs = deflate_comp_tv_template,
+                                       .count = DEFLATE_COMP_TEST_VECTORS
+                               },
+                               .decomp = {
+                                       .vecs = deflate_decomp_tv_template,
+                                       .count = DEFLATE_DECOMP_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(aes)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = aes_enc_tv_template,
+                                       .count = AES_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = aes_dec_tv_template,
+                                       .count = AES_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(anubis)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = anubis_enc_tv_template,
+                                       .count = ANUBIS_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = anubis_dec_tv_template,
+                                       .count = ANUBIS_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(arc4)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = arc4_enc_tv_template,
+                                       .count = ARC4_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = arc4_dec_tv_template,
+                                       .count = ARC4_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(blowfish)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = bf_enc_tv_template,
+                                       .count = BF_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = bf_dec_tv_template,
+                                       .count = BF_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(camellia)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = camellia_enc_tv_template,
+                                       .count = CAMELLIA_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = camellia_dec_tv_template,
+                                       .count = CAMELLIA_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(cast5)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = cast5_enc_tv_template,
+                                       .count = CAST5_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = cast5_dec_tv_template,
+                                       .count = CAST5_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(cast6)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = cast6_enc_tv_template,
+                                       .count = CAST6_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = cast6_dec_tv_template,
+                                       .count = CAST6_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(des)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = des_enc_tv_template,
+                                       .count = DES_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = des_dec_tv_template,
+                                       .count = DES_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(des3_ede)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = des3_ede_enc_tv_template,
+                                       .count = DES3_EDE_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = des3_ede_dec_tv_template,
+                                       .count = DES3_EDE_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(khazad)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = khazad_enc_tv_template,
+                                       .count = KHAZAD_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = khazad_dec_tv_template,
+                                       .count = KHAZAD_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(seed)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = seed_enc_tv_template,
+                                       .count = SEED_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = seed_dec_tv_template,
+                                       .count = SEED_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(serpent)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = serpent_enc_tv_template,
+                                       .count = SERPENT_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = serpent_dec_tv_template,
+                                       .count = SERPENT_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(tea)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = tea_enc_tv_template,
+                                       .count = TEA_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = tea_dec_tv_template,
+                                       .count = TEA_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(tnepres)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = tnepres_enc_tv_template,
+                                       .count = TNEPRES_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = tnepres_dec_tv_template,
+                                       .count = TNEPRES_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(twofish)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = tf_enc_tv_template,
+                                       .count = TF_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = tf_dec_tv_template,
+                                       .count = TF_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(xeta)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = xeta_enc_tv_template,
+                                       .count = XETA_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = xeta_dec_tv_template,
+                                       .count = XETA_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "ecb(xtea)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = xtea_enc_tv_template,
+                                       .count = XTEA_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = xtea_dec_tv_template,
+                                       .count = XTEA_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "gcm(aes)",
+               .test = alg_test_aead,
+               .suite = {
+                       .aead = {
+                               .enc = {
+                                       .vecs = aes_gcm_enc_tv_template,
+                                       .count = AES_GCM_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = aes_gcm_dec_tv_template,
+                                       .count = AES_GCM_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "hmac(md5)",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = hmac_md5_tv_template,
+                               .count = HMAC_MD5_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "hmac(rmd128)",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = hmac_rmd128_tv_template,
+                               .count = HMAC_RMD128_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "hmac(rmd160)",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = hmac_rmd160_tv_template,
+                               .count = HMAC_RMD160_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "hmac(sha1)",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = hmac_sha1_tv_template,
+                               .count = HMAC_SHA1_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "hmac(sha224)",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = hmac_sha224_tv_template,
+                               .count = HMAC_SHA224_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "hmac(sha256)",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = hmac_sha256_tv_template,
+                               .count = HMAC_SHA256_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "hmac(sha384)",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = hmac_sha384_tv_template,
+                               .count = HMAC_SHA384_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "hmac(sha512)",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = hmac_sha512_tv_template,
+                               .count = HMAC_SHA512_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "lrw(aes)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = aes_lrw_enc_tv_template,
+                                       .count = AES_LRW_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = aes_lrw_dec_tv_template,
+                                       .count = AES_LRW_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "lzo",
+               .test = alg_test_comp,
+               .suite = {
+                       .comp = {
+                               .comp = {
+                                       .vecs = lzo_comp_tv_template,
+                                       .count = LZO_COMP_TEST_VECTORS
+                               },
+                               .decomp = {
+                                       .vecs = lzo_decomp_tv_template,
+                                       .count = LZO_DECOMP_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "md4",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = md4_tv_template,
+                               .count = MD4_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "md5",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = md5_tv_template,
+                               .count = MD5_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "michael_mic",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = michael_mic_tv_template,
+                               .count = MICHAEL_MIC_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "pcbc(fcrypt)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = fcrypt_pcbc_enc_tv_template,
+                                       .count = FCRYPT_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = fcrypt_pcbc_dec_tv_template,
+                                       .count = FCRYPT_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "rfc3686(ctr(aes))",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = aes_ctr_enc_tv_template,
+                                       .count = AES_CTR_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = aes_ctr_dec_tv_template,
+                                       .count = AES_CTR_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "rmd128",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = rmd128_tv_template,
+                               .count = RMD128_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "rmd160",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = rmd160_tv_template,
+                               .count = RMD160_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "rmd256",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = rmd256_tv_template,
+                               .count = RMD256_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "rmd320",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = rmd320_tv_template,
+                               .count = RMD320_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "salsa20",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = salsa20_stream_enc_tv_template,
+                                       .count = SALSA20_STREAM_ENC_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "sha1",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = sha1_tv_template,
+                               .count = SHA1_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "sha224",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = sha224_tv_template,
+                               .count = SHA224_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "sha256",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = sha256_tv_template,
+                               .count = SHA256_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "sha384",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = sha384_tv_template,
+                               .count = SHA384_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "sha512",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = sha512_tv_template,
+                               .count = SHA512_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "tgr128",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = tgr128_tv_template,
+                               .count = TGR128_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "tgr160",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = tgr160_tv_template,
+                               .count = TGR160_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "tgr192",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = tgr192_tv_template,
+                               .count = TGR192_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "wp256",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = wp256_tv_template,
+                               .count = WP256_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "wp384",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = wp384_tv_template,
+                               .count = WP384_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "wp512",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = wp512_tv_template,
+                               .count = WP512_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "xcbc(aes)",
+               .test = alg_test_hash,
+               .suite = {
+                       .hash = {
+                               .vecs = aes_xcbc128_tv_template,
+                               .count = XCBC_AES_TEST_VECTORS
+                       }
+               }
+       }, {
+               .alg = "xts(aes)",
+               .test = alg_test_skcipher,
+               .suite = {
+                       .cipher = {
+                               .enc = {
+                                       .vecs = aes_xts_enc_tv_template,
+                                       .count = AES_XTS_ENC_TEST_VECTORS
+                               },
+                               .dec = {
+                                       .vecs = aes_xts_dec_tv_template,
+                                       .count = AES_XTS_DEC_TEST_VECTORS
+                               }
+                       }
+               }
+       }
+};
+
+static int alg_find_test(const char *alg)
+{
+       int start = 0;
+       int end = ARRAY_SIZE(alg_test_descs);
+
+       while (start < end) {
+               int i = (start + end) / 2;
+               int diff = strcmp(alg_test_descs[i].alg, alg);
+
+               if (diff > 0) {
+                       end = i;
+                       continue;
+               }
+
+               if (diff < 0) {
+                       start = i + 1;
+                       continue;
+               }
+
+               return i;
+       }
+
+       return -1;
+}
+
+int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
+{
+       int i;
+
+       if ((type & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_CIPHER) {
+               char nalg[CRYPTO_MAX_ALG_NAME];
+
+               if (snprintf(nalg, sizeof(nalg), "ecb(%s)", alg) >=
+                   sizeof(nalg))
+                       return -ENAMETOOLONG;
+
+               i = alg_find_test(nalg);
+               if (i < 0)
+                       goto notest;
+
+               return alg_test_cipher(alg_test_descs + i, driver, type, mask);
+       }
+
+       i = alg_find_test(alg);
+       if (i < 0)
+               goto notest;
+
+       return alg_test_descs[i].test(alg_test_descs + i, driver,
+                                     type, mask);
+
+notest:
+       printk(KERN_INFO "alg: No test for %s (%s)\n", alg, driver);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(alg_test);
+
+int __init testmgr_init(void)
+{
+       int i;
+
+       for (i = 0; i < XBUFSIZE; i++) {
+               xbuf[i] = (void *)__get_free_page(GFP_KERNEL);
+               if (!xbuf[i])
+                       goto err_free_xbuf;
+       }
+
+       for (i = 0; i < XBUFSIZE; i++) {
+               axbuf[i] = (void *)__get_free_page(GFP_KERNEL);
+               if (!axbuf[i])
+                       goto err_free_axbuf;
+       }
+
+       return 0;
+
+err_free_axbuf:
+       for (i = 0; i < XBUFSIZE && axbuf[i]; i++)
+               free_page((unsigned long)axbuf[i]);
+err_free_xbuf:
+       for (i = 0; i < XBUFSIZE && xbuf[i]; i++)
+               free_page((unsigned long)xbuf[i]);
+
+       return -ENOMEM;
+}
+
+void testmgr_exit(void)
+{
+       int i;
+
+       for (i = 0; i < XBUFSIZE; i++)
+               free_page((unsigned long)axbuf[i]);
+       for (i = 0; i < XBUFSIZE; i++)
+               free_page((unsigned long)xbuf[i]);
+}
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
new file mode 100644 (file)
index 0000000..dee94d9
--- /dev/null
@@ -0,0 +1,8738 @@
+/*
+ * Algorithm testing framework and tests.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ * Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org>
+ * Copyright (c) 2007 Nokia Siemens Networks
+ * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au>
+ *
+ * This program 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.
+ *
+ */
+#ifndef _CRYPTO_TESTMGR_H
+#define _CRYPTO_TESTMGR_H
+
+#define MAX_DIGEST_SIZE                64
+#define MAX_TAP                        8
+
+#define MAX_KEYLEN             56
+#define MAX_IVLEN              32
+
+struct hash_testvec {
+       /* only used with keyed hash algorithms */
+       char *key;
+       char *plaintext;
+       char *digest;
+       unsigned char tap[MAX_TAP];
+       unsigned char psize;
+       unsigned char np;
+       unsigned char ksize;
+};
+
+struct cipher_testvec {
+       char *key;
+       char *iv;
+       char *input;
+       char *result;
+       unsigned short tap[MAX_TAP];
+       int np;
+       unsigned char fail;
+       unsigned char wk; /* weak key flag */
+       unsigned char klen;
+       unsigned short ilen;
+       unsigned short rlen;
+};
+
+struct aead_testvec {
+       char *key;
+       char *iv;
+       char *input;
+       char *assoc;
+       char *result;
+       unsigned char tap[MAX_TAP];
+       unsigned char atap[MAX_TAP];
+       int np;
+       int anp;
+       unsigned char fail;
+       unsigned char wk; /* weak key flag */
+       unsigned char klen;
+       unsigned short ilen;
+       unsigned short alen;
+       unsigned short rlen;
+};
+
+static char zeroed_string[48];
+
+/*
+ * MD4 test vectors from RFC1320
+ */
+#define MD4_TEST_VECTORS       7
+
+static struct hash_testvec md4_tv_template [] = {
+       {
+               .plaintext = "",
+               .digest = "\x31\xd6\xcf\xe0\xd1\x6a\xe9\x31"
+                         "\xb7\x3c\x59\xd7\xe0\xc0\x89\xc0",
+       }, {
+               .plaintext = "a",
+               .psize  = 1,
+               .digest = "\xbd\xe5\x2c\xb3\x1d\xe3\x3e\x46"
+                         "\x24\x5e\x05\xfb\xdb\xd6\xfb\x24",
+       }, {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\xa4\x48\x01\x7a\xaf\x21\xd8\x52"
+                         "\x5f\xc1\x0a\xe8\x7a\xa6\x72\x9d",
+       }, {
+               .plaintext = "message digest",
+               .psize  = 14,
+               .digest = "\xd9\x13\x0a\x81\x64\x54\x9f\xe8"
+                       "\x18\x87\x48\x06\xe1\xc7\x01\x4b",
+       }, {
+               .plaintext = "abcdefghijklmnopqrstuvwxyz",
+               .psize  = 26,
+               .digest = "\xd7\x9e\x1c\x30\x8a\xa5\xbb\xcd"
+                         "\xee\xa8\xed\x63\xdf\x41\x2d\xa9",
+               .np     = 2,
+               .tap    = { 13, 13 },
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+               .psize  = 62,
+               .digest = "\x04\x3f\x85\x82\xf2\x41\xdb\x35"
+                         "\x1c\xe6\x27\xe1\x53\xe7\xf0\xe4",
+       }, {
+               .plaintext = "123456789012345678901234567890123456789012345678901234567890123"
+                          "45678901234567890",
+               .psize  = 80,
+               .digest = "\xe3\x3b\x4d\xdc\x9c\x38\xf2\x19"
+                         "\x9c\x3e\x7b\x16\x4f\xcc\x05\x36",
+       },
+};
+
+/*
+ * MD5 test vectors from RFC1321
+ */
+#define MD5_TEST_VECTORS       7
+
+static struct hash_testvec md5_tv_template[] = {
+       {
+               .digest = "\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04"
+                         "\xe9\x80\x09\x98\xec\xf8\x42\x7e",
+       }, {
+               .plaintext = "a",
+               .psize  = 1,
+               .digest = "\x0c\xc1\x75\xb9\xc0\xf1\xb6\xa8"
+                         "\x31\xc3\x99\xe2\x69\x77\x26\x61",
+       }, {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\x90\x01\x50\x98\x3c\xd2\x4f\xb0"
+                         "\xd6\x96\x3f\x7d\x28\xe1\x7f\x72",
+       }, {
+               .plaintext = "message digest",
+               .psize  = 14,
+               .digest = "\xf9\x6b\x69\x7d\x7c\xb7\x93\x8d"
+                         "\x52\x5a\x2f\x31\xaa\xf1\x61\xd0",
+       }, {
+               .plaintext = "abcdefghijklmnopqrstuvwxyz",
+               .psize  = 26,
+               .digest = "\xc3\xfc\xd3\xd7\x61\x92\xe4\x00"
+                         "\x7d\xfb\x49\x6c\xca\x67\xe1\x3b",
+               .np     = 2,
+               .tap    = {13, 13}
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+               .psize  = 62,
+               .digest = "\xd1\x74\xab\x98\xd2\x77\xd9\xf5"
+                         "\xa5\x61\x1c\x2c\x9f\x41\x9d\x9f",
+       }, {
+               .plaintext = "12345678901234567890123456789012345678901234567890123456789012"
+                          "345678901234567890",
+               .psize  = 80,
+               .digest = "\x57\xed\xf4\xa2\x2b\xe3\xc9\x55"
+                         "\xac\x49\xda\x2e\x21\x07\xb6\x7a",
+       }
+
+};
+
+/*
+ * RIPEMD-128 test vectors from ISO/IEC 10118-3:2004(E)
+ */
+#define RMD128_TEST_VECTORS     10
+
+static struct hash_testvec rmd128_tv_template[] = {
+       {
+               .digest = "\xcd\xf2\x62\x13\xa1\x50\xdc\x3e"
+                         "\xcb\x61\x0f\x18\xf6\xb3\x8b\x46",
+       }, {
+               .plaintext = "a",
+               .psize  = 1,
+               .digest = "\x86\xbe\x7a\xfa\x33\x9d\x0f\xc7"
+                         "\xcf\xc7\x85\xe7\x2f\x57\x8d\x33",
+       }, {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\xc1\x4a\x12\x19\x9c\x66\xe4\xba"
+                         "\x84\x63\x6b\x0f\x69\x14\x4c\x77",
+       }, {
+               .plaintext = "message digest",
+               .psize  = 14,
+               .digest = "\x9e\x32\x7b\x3d\x6e\x52\x30\x62"
+                         "\xaf\xc1\x13\x2d\x7d\xf9\xd1\xb8",
+       }, {
+               .plaintext = "abcdefghijklmnopqrstuvwxyz",
+               .psize  = 26,
+               .digest = "\xfd\x2a\xa6\x07\xf7\x1d\xc8\xf5"
+                         "\x10\x71\x49\x22\xb3\x71\x83\x4e",
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"
+                            "fghijklmnopqrstuvwxyz0123456789",
+               .psize  = 62,
+               .digest = "\xd1\xe9\x59\xeb\x17\x9c\x91\x1f"
+                         "\xae\xa4\x62\x4c\x60\xc5\xc7\x02",
+       }, {
+               .plaintext = "1234567890123456789012345678901234567890"
+                            "1234567890123456789012345678901234567890",
+               .psize  = 80,
+               .digest = "\x3f\x45\xef\x19\x47\x32\xc2\xdb"
+                         "\xb2\xc4\xa2\xc7\x69\x79\x5f\xa3",
+       }, {
+               .plaintext = "abcdbcdecdefdefgefghfghighij"
+                            "hijkijkljklmklmnlmnomnopnopq",
+               .psize  = 56,
+               .digest = "\xa1\xaa\x06\x89\xd0\xfa\xfa\x2d"
+                         "\xdc\x22\xe8\x8b\x49\x13\x3a\x06",
+               .np     = 2,
+               .tap    = { 28, 28 },
+       }, {
+               .plaintext = "abcdefghbcdefghicdefghijdefghijkefghijklfghi"
+                            "jklmghijklmnhijklmnoijklmnopjklmnopqklmnopqr"
+                            "lmnopqrsmnopqrstnopqrstu",
+               .psize  = 112,
+               .digest = "\xd4\xec\xc9\x13\xe1\xdf\x77\x6b"
+                         "\xf4\x8d\xe9\xd5\x5b\x1f\x25\x46",
+       }, {
+               .plaintext = "abcdbcdecdefdefgefghfghighijhijk",
+               .psize  = 32,
+               .digest = "\x13\xfc\x13\xe8\xef\xff\x34\x7d"
+                         "\xe1\x93\xff\x46\xdb\xac\xcf\xd4",
+       }
+};
+
+/*
+ * RIPEMD-160 test vectors from ISO/IEC 10118-3:2004(E)
+ */
+#define RMD160_TEST_VECTORS     10
+
+static struct hash_testvec rmd160_tv_template[] = {
+       {
+               .digest = "\x9c\x11\x85\xa5\xc5\xe9\xfc\x54\x61\x28"
+                         "\x08\x97\x7e\xe8\xf5\x48\xb2\x25\x8d\x31",
+       }, {
+               .plaintext = "a",
+               .psize  = 1,
+               .digest = "\x0b\xdc\x9d\x2d\x25\x6b\x3e\xe9\xda\xae"
+                         "\x34\x7b\xe6\xf4\xdc\x83\x5a\x46\x7f\xfe",
+       }, {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\x8e\xb2\x08\xf7\xe0\x5d\x98\x7a\x9b\x04"
+                         "\x4a\x8e\x98\xc6\xb0\x87\xf1\x5a\x0b\xfc",
+       }, {
+               .plaintext = "message digest",
+               .psize  = 14,
+               .digest = "\x5d\x06\x89\xef\x49\xd2\xfa\xe5\x72\xb8"
+                         "\x81\xb1\x23\xa8\x5f\xfa\x21\x59\x5f\x36",
+       }, {
+               .plaintext = "abcdefghijklmnopqrstuvwxyz",
+               .psize  = 26,
+               .digest = "\xf7\x1c\x27\x10\x9c\x69\x2c\x1b\x56\xbb"
+                         "\xdc\xeb\x5b\x9d\x28\x65\xb3\x70\x8d\xbc",
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"
+                            "fghijklmnopqrstuvwxyz0123456789",
+               .psize  = 62,
+               .digest = "\xb0\xe2\x0b\x6e\x31\x16\x64\x02\x86\xed"
+                         "\x3a\x87\xa5\x71\x30\x79\xb2\x1f\x51\x89",
+       }, {
+               .plaintext = "1234567890123456789012345678901234567890"
+                            "1234567890123456789012345678901234567890",
+               .psize  = 80,
+               .digest = "\x9b\x75\x2e\x45\x57\x3d\x4b\x39\xf4\xdb"
+                         "\xd3\x32\x3c\xab\x82\xbf\x63\x32\x6b\xfb",
+       }, {
+               .plaintext = "abcdbcdecdefdefgefghfghighij"
+                            "hijkijkljklmklmnlmnomnopnopq",
+               .psize  = 56,
+               .digest = "\x12\xa0\x53\x38\x4a\x9c\x0c\x88\xe4\x05"
+                         "\xa0\x6c\x27\xdc\xf4\x9a\xda\x62\xeb\x2b",
+               .np     = 2,
+               .tap    = { 28, 28 },
+       }, {
+               .plaintext = "abcdefghbcdefghicdefghijdefghijkefghijklfghi"
+                            "jklmghijklmnhijklmnoijklmnopjklmnopqklmnopqr"
+                            "lmnopqrsmnopqrstnopqrstu",
+               .psize  = 112,
+               .digest = "\x6f\x3f\xa3\x9b\x6b\x50\x3c\x38\x4f\x91"
+                         "\x9a\x49\xa7\xaa\x5c\x2c\x08\xbd\xfb\x45",
+       }, {
+               .plaintext = "abcdbcdecdefdefgefghfghighijhijk",
+               .psize  = 32,
+               .digest = "\x94\xc2\x64\x11\x54\x04\xe6\x33\x79\x0d"
+                         "\xfc\xc8\x7b\x58\x7d\x36\x77\x06\x7d\x9f",
+       }
+};
+
+/*
+ * RIPEMD-256 test vectors
+ */
+#define RMD256_TEST_VECTORS     8
+
+static struct hash_testvec rmd256_tv_template[] = {
+       {
+               .digest = "\x02\xba\x4c\x4e\x5f\x8e\xcd\x18"
+                         "\x77\xfc\x52\xd6\x4d\x30\xe3\x7a"
+                         "\x2d\x97\x74\xfb\x1e\x5d\x02\x63"
+                         "\x80\xae\x01\x68\xe3\xc5\x52\x2d",
+       }, {
+               .plaintext = "a",
+               .psize  = 1,
+               .digest = "\xf9\x33\x3e\x45\xd8\x57\xf5\xd9"
+                         "\x0a\x91\xba\xb7\x0a\x1e\xba\x0c"
+                         "\xfb\x1b\xe4\xb0\x78\x3c\x9a\xcf"
+                         "\xcd\x88\x3a\x91\x34\x69\x29\x25",
+       }, {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\xaf\xbd\x6e\x22\x8b\x9d\x8c\xbb"
+                         "\xce\xf5\xca\x2d\x03\xe6\xdb\xa1"
+                         "\x0a\xc0\xbc\x7d\xcb\xe4\x68\x0e"
+                         "\x1e\x42\xd2\xe9\x75\x45\x9b\x65",
+       }, {
+               .plaintext = "message digest",
+               .psize  = 14,
+               .digest = "\x87\xe9\x71\x75\x9a\x1c\xe4\x7a"
+                         "\x51\x4d\x5c\x91\x4c\x39\x2c\x90"
+                         "\x18\xc7\xc4\x6b\xc1\x44\x65\x55"
+                         "\x4a\xfc\xdf\x54\xa5\x07\x0c\x0e",
+       }, {
+               .plaintext = "abcdefghijklmnopqrstuvwxyz",
+               .psize  = 26,
+               .digest = "\x64\x9d\x30\x34\x75\x1e\xa2\x16"
+                         "\x77\x6b\xf9\xa1\x8a\xcc\x81\xbc"
+                         "\x78\x96\x11\x8a\x51\x97\x96\x87"
+                         "\x82\xdd\x1f\xd9\x7d\x8d\x51\x33",
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"
+                            "fghijklmnopqrstuvwxyz0123456789",
+               .psize  = 62,
+               .digest = "\x57\x40\xa4\x08\xac\x16\xb7\x20"
+                         "\xb8\x44\x24\xae\x93\x1c\xbb\x1f"
+                         "\xe3\x63\xd1\xd0\xbf\x40\x17\xf1"
+                         "\xa8\x9f\x7e\xa6\xde\x77\xa0\xb8",
+       }, {
+               .plaintext = "1234567890123456789012345678901234567890"
+                            "1234567890123456789012345678901234567890",
+               .psize  = 80,
+               .digest = "\x06\xfd\xcc\x7a\x40\x95\x48\xaa"
+                         "\xf9\x13\x68\xc0\x6a\x62\x75\xb5"
+                         "\x53\xe3\xf0\x99\xbf\x0e\xa4\xed"
+                         "\xfd\x67\x78\xdf\x89\xa8\x90\xdd",
+       }, {
+               .plaintext = "abcdbcdecdefdefgefghfghighij"
+                            "hijkijkljklmklmnlmnomnopnopq",
+               .psize  = 56,
+               .digest = "\x38\x43\x04\x55\x83\xaa\xc6\xc8"
+                         "\xc8\xd9\x12\x85\x73\xe7\xa9\x80"
+                         "\x9a\xfb\x2a\x0f\x34\xcc\xc3\x6e"
+                         "\xa9\xe7\x2f\x16\xf6\x36\x8e\x3f",
+               .np     = 2,
+               .tap    = { 28, 28 },
+       }
+};
+
+/*
+ * RIPEMD-320 test vectors
+ */
+#define RMD320_TEST_VECTORS     8
+
+static struct hash_testvec rmd320_tv_template[] = {
+       {
+               .digest = "\x22\xd6\x5d\x56\x61\x53\x6c\xdc\x75\xc1"
+                         "\xfd\xf5\xc6\xde\x7b\x41\xb9\xf2\x73\x25"
+                         "\xeb\xc6\x1e\x85\x57\x17\x7d\x70\x5a\x0e"
+                         "\xc8\x80\x15\x1c\x3a\x32\xa0\x08\x99\xb8",
+       }, {
+               .plaintext = "a",
+               .psize  = 1,
+               .digest = "\xce\x78\x85\x06\x38\xf9\x26\x58\xa5\xa5"
+                         "\x85\x09\x75\x79\x92\x6d\xda\x66\x7a\x57"
+                         "\x16\x56\x2c\xfc\xf6\xfb\xe7\x7f\x63\x54"
+                         "\x2f\x99\xb0\x47\x05\xd6\x97\x0d\xff\x5d",
+       }, {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\xde\x4c\x01\xb3\x05\x4f\x89\x30\xa7\x9d"
+                         "\x09\xae\x73\x8e\x92\x30\x1e\x5a\x17\x08"
+                         "\x5b\xef\xfd\xc1\xb8\xd1\x16\x71\x3e\x74"
+                         "\xf8\x2f\xa9\x42\xd6\x4c\xdb\xc4\x68\x2d",
+       }, {
+               .plaintext = "message digest",
+               .psize  = 14,
+               .digest = "\x3a\x8e\x28\x50\x2e\xd4\x5d\x42\x2f\x68"
+                         "\x84\x4f\x9d\xd3\x16\xe7\xb9\x85\x33\xfa"
+                         "\x3f\x2a\x91\xd2\x9f\x84\xd4\x25\xc8\x8d"
+                         "\x6b\x4e\xff\x72\x7d\xf6\x6a\x7c\x01\x97",
+       }, {
+               .plaintext = "abcdefghijklmnopqrstuvwxyz",
+               .psize  = 26,
+               .digest = "\xca\xbd\xb1\x81\x0b\x92\x47\x0a\x20\x93"
+                         "\xaa\x6b\xce\x05\x95\x2c\x28\x34\x8c\xf4"
+                         "\x3f\xf6\x08\x41\x97\x51\x66\xbb\x40\xed"
+                         "\x23\x40\x04\xb8\x82\x44\x63\xe6\xb0\x09",
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"
+                            "fghijklmnopqrstuvwxyz0123456789",
+               .psize  = 62,
+               .digest = "\xed\x54\x49\x40\xc8\x6d\x67\xf2\x50\xd2"
+                         "\x32\xc3\x0b\x7b\x3e\x57\x70\xe0\xc6\x0c"
+                         "\x8c\xb9\xa4\xca\xfe\x3b\x11\x38\x8a\xf9"
+                         "\x92\x0e\x1b\x99\x23\x0b\x84\x3c\x86\xa4",
+       }, {
+               .plaintext = "1234567890123456789012345678901234567890"
+                            "1234567890123456789012345678901234567890",
+               .psize  = 80,
+               .digest = "\x55\x78\x88\xaf\x5f\x6d\x8e\xd6\x2a\xb6"
+                         "\x69\x45\xc6\xd2\xa0\xa4\x7e\xcd\x53\x41"
+                         "\xe9\x15\xeb\x8f\xea\x1d\x05\x24\x95\x5f"
+                         "\x82\x5d\xc7\x17\xe4\xa0\x08\xab\x2d\x42",
+       }, {
+               .plaintext = "abcdbcdecdefdefgefghfghighij"
+                            "hijkijkljklmklmnlmnomnopnopq",
+               .psize  = 56,
+               .digest = "\xd0\x34\xa7\x95\x0c\xf7\x22\x02\x1b\xa4"
+                         "\xb8\x4d\xf7\x69\xa5\xde\x20\x60\xe2\x59"
+                         "\xdf\x4c\x9b\xb4\xa4\x26\x8c\x0e\x93\x5b"
+                         "\xbc\x74\x70\xa9\x69\xc9\xd0\x72\xa1\xac",
+               .np     = 2,
+               .tap    = { 28, 28 },
+       }
+};
+
+/*
+ * SHA1 test vectors  from from FIPS PUB 180-1
+ */
+#define SHA1_TEST_VECTORS      2
+
+static struct hash_testvec sha1_tv_template[] = {
+       {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\xa9\x99\x3e\x36\x47\x06\x81\x6a\xba\x3e"
+                         "\x25\x71\x78\x50\xc2\x6c\x9c\xd0\xd8\x9d",
+       }, {
+               .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+               .psize  = 56,
+               .digest = "\x84\x98\x3e\x44\x1c\x3b\xd2\x6e\xba\xae"
+                         "\x4a\xa1\xf9\x51\x29\xe5\xe5\x46\x70\xf1",
+               .np     = 2,
+               .tap    = { 28, 28 }
+       }
+};
+
+
+/*
+ * SHA224 test vectors from from FIPS PUB 180-2
+ */
+#define SHA224_TEST_VECTORS     2
+
+static struct hash_testvec sha224_tv_template[] = {
+       {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\x23\x09\x7D\x22\x34\x05\xD8\x22"
+                         "\x86\x42\xA4\x77\xBD\xA2\x55\xB3"
+                         "\x2A\xAD\xBC\xE4\xBD\xA0\xB3\xF7"
+                         "\xE3\x6C\x9D\xA7",
+       }, {
+               .plaintext =
+               "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+               .psize  = 56,
+               .digest = "\x75\x38\x8B\x16\x51\x27\x76\xCC"
+                         "\x5D\xBA\x5D\xA1\xFD\x89\x01\x50"
+                         "\xB0\xC6\x45\x5C\xB4\xF5\x8B\x19"
+                         "\x52\x52\x25\x25",
+               .np     = 2,
+               .tap    = { 28, 28 }
+       }
+};
+
+/*
+ * SHA256 test vectors from from NIST
+ */
+#define SHA256_TEST_VECTORS    2
+
+static struct hash_testvec sha256_tv_template[] = {
+       {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\xba\x78\x16\xbf\x8f\x01\xcf\xea"
+                         "\x41\x41\x40\xde\x5d\xae\x22\x23"
+                         "\xb0\x03\x61\xa3\x96\x17\x7a\x9c"
+                         "\xb4\x10\xff\x61\xf2\x00\x15\xad",
+       }, {
+               .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+               .psize  = 56,
+               .digest = "\x24\x8d\x6a\x61\xd2\x06\x38\xb8"
+                         "\xe5\xc0\x26\x93\x0c\x3e\x60\x39"
+                         "\xa3\x3c\xe4\x59\x64\xff\x21\x67"
+                         "\xf6\xec\xed\xd4\x19\xdb\x06\xc1",
+               .np     = 2,
+               .tap    = { 28, 28 }
+       },
+};
+
+/*
+ * SHA384 test vectors from from NIST and kerneli
+ */
+#define SHA384_TEST_VECTORS    4
+
+static struct hash_testvec sha384_tv_template[] = {
+       {
+               .plaintext= "abc",
+               .psize  = 3,
+               .digest = "\xcb\x00\x75\x3f\x45\xa3\x5e\x8b"
+                         "\xb5\xa0\x3d\x69\x9a\xc6\x50\x07"
+                         "\x27\x2c\x32\xab\x0e\xde\xd1\x63"
+                         "\x1a\x8b\x60\x5a\x43\xff\x5b\xed"
+                         "\x80\x86\x07\x2b\xa1\xe7\xcc\x23"
+                         "\x58\xba\xec\xa1\x34\xc8\x25\xa7",
+       }, {
+               .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+               .psize  = 56,
+               .digest = "\x33\x91\xfd\xdd\xfc\x8d\xc7\x39"
+                         "\x37\x07\xa6\x5b\x1b\x47\x09\x39"
+                         "\x7c\xf8\xb1\xd1\x62\xaf\x05\xab"
+                         "\xfe\x8f\x45\x0d\xe5\xf3\x6b\xc6"
+                         "\xb0\x45\x5a\x85\x20\xbc\x4e\x6f"
+                         "\x5f\xe9\x5b\x1f\xe3\xc8\x45\x2b",
+       }, {
+               .plaintext = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+                          "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+               .psize  = 112,
+               .digest = "\x09\x33\x0c\x33\xf7\x11\x47\xe8"
+                         "\x3d\x19\x2f\xc7\x82\xcd\x1b\x47"
+                         "\x53\x11\x1b\x17\x3b\x3b\x05\xd2"
+                         "\x2f\xa0\x80\x86\xe3\xb0\xf7\x12"
+                         "\xfc\xc7\xc7\x1a\x55\x7e\x2d\xb9"
+                         "\x66\xc3\xe9\xfa\x91\x74\x60\x39",
+       }, {
+               .plaintext = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd"
+                          "efghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz",
+               .psize  = 104,
+               .digest = "\x3d\x20\x89\x73\xab\x35\x08\xdb"
+                         "\xbd\x7e\x2c\x28\x62\xba\x29\x0a"
+                         "\xd3\x01\x0e\x49\x78\xc1\x98\xdc"
+                         "\x4d\x8f\xd0\x14\xe5\x82\x82\x3a"
+                         "\x89\xe1\x6f\x9b\x2a\x7b\xbc\x1a"
+                         "\xc9\x38\xe2\xd1\x99\xe8\xbe\xa4",
+               .np     = 4,
+               .tap    = { 26, 26, 26, 26 }
+       },
+};
+
+/*
+ * SHA512 test vectors from from NIST and kerneli
+ */
+#define SHA512_TEST_VECTORS    4
+
+static struct hash_testvec sha512_tv_template[] = {
+       {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\xdd\xaf\x35\xa1\x93\x61\x7a\xba"
+                         "\xcc\x41\x73\x49\xae\x20\x41\x31"
+                         "\x12\xe6\xfa\x4e\x89\xa9\x7e\xa2"
+                         "\x0a\x9e\xee\xe6\x4b\x55\xd3\x9a"
+                         "\x21\x92\x99\x2a\x27\x4f\xc1\xa8"
+                         "\x36\xba\x3c\x23\xa3\xfe\xeb\xbd"
+                         "\x45\x4d\x44\x23\x64\x3c\xe8\x0e"
+                         "\x2a\x9a\xc9\x4f\xa5\x4c\xa4\x9f",
+       }, {
+               .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+               .psize  = 56,
+               .digest = "\x20\x4a\x8f\xc6\xdd\xa8\x2f\x0a"
+                         "\x0c\xed\x7b\xeb\x8e\x08\xa4\x16"
+                         "\x57\xc1\x6e\xf4\x68\xb2\x28\xa8"
+                         "\x27\x9b\xe3\x31\xa7\x03\xc3\x35"
+                         "\x96\xfd\x15\xc1\x3b\x1b\x07\xf9"
+                         "\xaa\x1d\x3b\xea\x57\x78\x9c\xa0"
+                         "\x31\xad\x85\xc7\xa7\x1d\xd7\x03"
+                         "\x54\xec\x63\x12\x38\xca\x34\x45",
+       }, {
+               .plaintext = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+                          "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+               .psize  = 112,
+               .digest = "\x8e\x95\x9b\x75\xda\xe3\x13\xda"
+                         "\x8c\xf4\xf7\x28\x14\xfc\x14\x3f"
+                         "\x8f\x77\x79\xc6\xeb\x9f\x7f\xa1"
+                         "\x72\x99\xae\xad\xb6\x88\x90\x18"
+                         "\x50\x1d\x28\x9e\x49\x00\xf7\xe4"
+                         "\x33\x1b\x99\xde\xc4\xb5\x43\x3a"
+                         "\xc7\xd3\x29\xee\xb6\xdd\x26\x54"
+                         "\x5e\x96\xe5\x5b\x87\x4b\xe9\x09",
+       }, {
+               .plaintext = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd"
+                          "efghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz",
+               .psize  = 104,
+               .digest = "\x93\x0d\x0c\xef\xcb\x30\xff\x11"
+                         "\x33\xb6\x89\x81\x21\xf1\xcf\x3d"
+                         "\x27\x57\x8a\xfc\xaf\xe8\x67\x7c"
+                         "\x52\x57\xcf\x06\x99\x11\xf7\x5d"
+                         "\x8f\x58\x31\xb5\x6e\xbf\xda\x67"
+                         "\xb2\x78\xe6\x6d\xff\x8b\x84\xfe"
+                         "\x2b\x28\x70\xf7\x42\xa5\x80\xd8"
+                         "\xed\xb4\x19\x87\x23\x28\x50\xc9",
+               .np     = 4,
+               .tap    = { 26, 26, 26, 26 }
+       },
+};
+
+
+/*
+ * WHIRLPOOL test vectors from Whirlpool package
+ * by Vincent Rijmen and Paulo S. L. M. Barreto as part of the NESSIE
+ * submission
+ */
+#define WP512_TEST_VECTORS     8
+
+static struct hash_testvec wp512_tv_template[] = {
+       {
+               .plaintext = "",
+               .psize  = 0,
+               .digest = "\x19\xFA\x61\xD7\x55\x22\xA4\x66"
+                         "\x9B\x44\xE3\x9C\x1D\x2E\x17\x26"
+                         "\xC5\x30\x23\x21\x30\xD4\x07\xF8"
+                         "\x9A\xFE\xE0\x96\x49\x97\xF7\xA7"
+                         "\x3E\x83\xBE\x69\x8B\x28\x8F\xEB"
+                         "\xCF\x88\xE3\xE0\x3C\x4F\x07\x57"
+                         "\xEA\x89\x64\xE5\x9B\x63\xD9\x37"
+                         "\x08\xB1\x38\xCC\x42\xA6\x6E\xB3",
+
+
+       }, {
+               .plaintext = "a",
+               .psize  = 1,
+               .digest = "\x8A\xCA\x26\x02\x79\x2A\xEC\x6F"
+                         "\x11\xA6\x72\x06\x53\x1F\xB7\xD7"
+                         "\xF0\xDF\xF5\x94\x13\x14\x5E\x69"
+                         "\x73\xC4\x50\x01\xD0\x08\x7B\x42"
+                         "\xD1\x1B\xC6\x45\x41\x3A\xEF\xF6"
+                         "\x3A\x42\x39\x1A\x39\x14\x5A\x59"
+                         "\x1A\x92\x20\x0D\x56\x01\x95\xE5"
+                         "\x3B\x47\x85\x84\xFD\xAE\x23\x1A",
+       }, {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\x4E\x24\x48\xA4\xC6\xF4\x86\xBB"
+                         "\x16\xB6\x56\x2C\x73\xB4\x02\x0B"
+                         "\xF3\x04\x3E\x3A\x73\x1B\xCE\x72"
+                         "\x1A\xE1\xB3\x03\xD9\x7E\x6D\x4C"
+                         "\x71\x81\xEE\xBD\xB6\xC5\x7E\x27"
+                         "\x7D\x0E\x34\x95\x71\x14\xCB\xD6"
+                         "\xC7\x97\xFC\x9D\x95\xD8\xB5\x82"
+                         "\xD2\x25\x29\x20\x76\xD4\xEE\xF5",
+       }, {
+               .plaintext = "message digest",
+               .psize  = 14,
+               .digest = "\x37\x8C\x84\xA4\x12\x6E\x2D\xC6"
+                         "\xE5\x6D\xCC\x74\x58\x37\x7A\xAC"
+                         "\x83\x8D\x00\x03\x22\x30\xF5\x3C"
+                         "\xE1\xF5\x70\x0C\x0F\xFB\x4D\x3B"
+                         "\x84\x21\x55\x76\x59\xEF\x55\xC1"
+                         "\x06\xB4\xB5\x2A\xC5\xA4\xAA\xA6"
+                         "\x92\xED\x92\x00\x52\x83\x8F\x33"
+                         "\x62\xE8\x6D\xBD\x37\xA8\x90\x3E",
+       }, {
+               .plaintext = "abcdefghijklmnopqrstuvwxyz",
+               .psize  = 26,
+               .digest = "\xF1\xD7\x54\x66\x26\x36\xFF\xE9"
+                         "\x2C\x82\xEB\xB9\x21\x2A\x48\x4A"
+                         "\x8D\x38\x63\x1E\xAD\x42\x38\xF5"
+                         "\x44\x2E\xE1\x3B\x80\x54\xE4\x1B"
+                         "\x08\xBF\x2A\x92\x51\xC3\x0B\x6A"
+                         "\x0B\x8A\xAE\x86\x17\x7A\xB4\xA6"
+                         "\xF6\x8F\x67\x3E\x72\x07\x86\x5D"
+                         "\x5D\x98\x19\xA3\xDB\xA4\xEB\x3B",
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                          "abcdefghijklmnopqrstuvwxyz0123456789",
+               .psize  = 62,
+               .digest = "\xDC\x37\xE0\x08\xCF\x9E\xE6\x9B"
+                         "\xF1\x1F\x00\xED\x9A\xBA\x26\x90"
+                         "\x1D\xD7\xC2\x8C\xDE\xC0\x66\xCC"
+                         "\x6A\xF4\x2E\x40\xF8\x2F\x3A\x1E"
+                         "\x08\xEB\xA2\x66\x29\x12\x9D\x8F"
+                         "\xB7\xCB\x57\x21\x1B\x92\x81\xA6"
+                         "\x55\x17\xCC\x87\x9D\x7B\x96\x21"
+                         "\x42\xC6\x5F\x5A\x7A\xF0\x14\x67",
+       }, {
+               .plaintext = "1234567890123456789012345678901234567890"
+                          "1234567890123456789012345678901234567890",
+               .psize  = 80,
+               .digest = "\x46\x6E\xF1\x8B\xAB\xB0\x15\x4D"
+                         "\x25\xB9\xD3\x8A\x64\x14\xF5\xC0"
+                         "\x87\x84\x37\x2B\xCC\xB2\x04\xD6"
+                         "\x54\x9C\x4A\xFA\xDB\x60\x14\x29"
+                         "\x4D\x5B\xD8\xDF\x2A\x6C\x44\xE5"
+                         "\x38\xCD\x04\x7B\x26\x81\xA5\x1A"
+                         "\x2C\x60\x48\x1E\x88\xC5\xA2\x0B"
+                         "\x2C\x2A\x80\xCF\x3A\x9A\x08\x3B",
+       }, {
+               .plaintext = "abcdbcdecdefdefgefghfghighijhijk",
+               .psize  = 32,
+               .digest = "\x2A\x98\x7E\xA4\x0F\x91\x70\x61"
+                         "\xF5\xD6\xF0\xA0\xE4\x64\x4F\x48"
+                         "\x8A\x7A\x5A\x52\xDE\xEE\x65\x62"
+                         "\x07\xC5\x62\xF9\x88\xE9\x5C\x69"
+                         "\x16\xBD\xC8\x03\x1B\xC5\xBE\x1B"
+                         "\x7B\x94\x76\x39\xFE\x05\x0B\x56"
+                         "\x93\x9B\xAA\xA0\xAD\xFF\x9A\xE6"
+                         "\x74\x5B\x7B\x18\x1C\x3B\xE3\xFD",
+       },
+};
+
+#define WP384_TEST_VECTORS     8
+
+static struct hash_testvec wp384_tv_template[] = {
+       {
+               .plaintext = "",
+               .psize  = 0,
+               .digest = "\x19\xFA\x61\xD7\x55\x22\xA4\x66"
+                         "\x9B\x44\xE3\x9C\x1D\x2E\x17\x26"
+                         "\xC5\x30\x23\x21\x30\xD4\x07\xF8"
+                         "\x9A\xFE\xE0\x96\x49\x97\xF7\xA7"
+                         "\x3E\x83\xBE\x69\x8B\x28\x8F\xEB"
+                         "\xCF\x88\xE3\xE0\x3C\x4F\x07\x57",
+
+
+       }, {
+               .plaintext = "a",
+               .psize  = 1,
+               .digest = "\x8A\xCA\x26\x02\x79\x2A\xEC\x6F"
+                         "\x11\xA6\x72\x06\x53\x1F\xB7\xD7"
+                         "\xF0\xDF\xF5\x94\x13\x14\x5E\x69"
+                         "\x73\xC4\x50\x01\xD0\x08\x7B\x42"
+                         "\xD1\x1B\xC6\x45\x41\x3A\xEF\xF6"
+                         "\x3A\x42\x39\x1A\x39\x14\x5A\x59",
+       }, {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\x4E\x24\x48\xA4\xC6\xF4\x86\xBB"
+                         "\x16\xB6\x56\x2C\x73\xB4\x02\x0B"
+                         "\xF3\x04\x3E\x3A\x73\x1B\xCE\x72"
+                         "\x1A\xE1\xB3\x03\xD9\x7E\x6D\x4C"
+                         "\x71\x81\xEE\xBD\xB6\xC5\x7E\x27"
+                         "\x7D\x0E\x34\x95\x71\x14\xCB\xD6",
+       }, {
+               .plaintext = "message digest",
+               .psize  = 14,
+               .digest = "\x37\x8C\x84\xA4\x12\x6E\x2D\xC6"
+                         "\xE5\x6D\xCC\x74\x58\x37\x7A\xAC"
+                         "\x83\x8D\x00\x03\x22\x30\xF5\x3C"
+                         "\xE1\xF5\x70\x0C\x0F\xFB\x4D\x3B"
+                         "\x84\x21\x55\x76\x59\xEF\x55\xC1"
+                         "\x06\xB4\xB5\x2A\xC5\xA4\xAA\xA6",
+       }, {
+               .plaintext = "abcdefghijklmnopqrstuvwxyz",
+               .psize  = 26,
+               .digest = "\xF1\xD7\x54\x66\x26\x36\xFF\xE9"
+                         "\x2C\x82\xEB\xB9\x21\x2A\x48\x4A"
+                         "\x8D\x38\x63\x1E\xAD\x42\x38\xF5"
+                         "\x44\x2E\xE1\x3B\x80\x54\xE4\x1B"
+                         "\x08\xBF\x2A\x92\x51\xC3\x0B\x6A"
+                         "\x0B\x8A\xAE\x86\x17\x7A\xB4\xA6",
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                          "abcdefghijklmnopqrstuvwxyz0123456789",
+               .psize  = 62,
+               .digest = "\xDC\x37\xE0\x08\xCF\x9E\xE6\x9B"
+                         "\xF1\x1F\x00\xED\x9A\xBA\x26\x90"
+                         "\x1D\xD7\xC2\x8C\xDE\xC0\x66\xCC"
+                         "\x6A\xF4\x2E\x40\xF8\x2F\x3A\x1E"
+                         "\x08\xEB\xA2\x66\x29\x12\x9D\x8F"
+                         "\xB7\xCB\x57\x21\x1B\x92\x81\xA6",
+       }, {
+               .plaintext = "1234567890123456789012345678901234567890"
+                          "1234567890123456789012345678901234567890",
+               .psize  = 80,
+               .digest = "\x46\x6E\xF1\x8B\xAB\xB0\x15\x4D"
+                         "\x25\xB9\xD3\x8A\x64\x14\xF5\xC0"
+                         "\x87\x84\x37\x2B\xCC\xB2\x04\xD6"
+                         "\x54\x9C\x4A\xFA\xDB\x60\x14\x29"
+                         "\x4D\x5B\xD8\xDF\x2A\x6C\x44\xE5"
+                         "\x38\xCD\x04\x7B\x26\x81\xA5\x1A",
+       }, {
+               .plaintext = "abcdbcdecdefdefgefghfghighijhijk",
+               .psize  = 32,
+               .digest = "\x2A\x98\x7E\xA4\x0F\x91\x70\x61"
+                         "\xF5\xD6\xF0\xA0\xE4\x64\x4F\x48"
+                         "\x8A\x7A\x5A\x52\xDE\xEE\x65\x62"
+                         "\x07\xC5\x62\xF9\x88\xE9\x5C\x69"
+                         "\x16\xBD\xC8\x03\x1B\xC5\xBE\x1B"
+                         "\x7B\x94\x76\x39\xFE\x05\x0B\x56",
+       },
+};
+
+#define WP256_TEST_VECTORS     8
+
+static struct hash_testvec wp256_tv_template[] = {
+       {
+               .plaintext = "",
+               .psize  = 0,
+               .digest = "\x19\xFA\x61\xD7\x55\x22\xA4\x66"
+                         "\x9B\x44\xE3\x9C\x1D\x2E\x17\x26"
+                         "\xC5\x30\x23\x21\x30\xD4\x07\xF8"
+                         "\x9A\xFE\xE0\x96\x49\x97\xF7\xA7",
+
+
+       }, {
+               .plaintext = "a",
+               .psize  = 1,
+               .digest = "\x8A\xCA\x26\x02\x79\x2A\xEC\x6F"
+                         "\x11\xA6\x72\x06\x53\x1F\xB7\xD7"
+                         "\xF0\xDF\xF5\x94\x13\x14\x5E\x69"
+                         "\x73\xC4\x50\x01\xD0\x08\x7B\x42",
+       }, {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\x4E\x24\x48\xA4\xC6\xF4\x86\xBB"
+                         "\x16\xB6\x56\x2C\x73\xB4\x02\x0B"
+                         "\xF3\x04\x3E\x3A\x73\x1B\xCE\x72"
+                         "\x1A\xE1\xB3\x03\xD9\x7E\x6D\x4C",
+       }, {
+               .plaintext = "message digest",
+               .psize  = 14,
+               .digest = "\x37\x8C\x84\xA4\x12\x6E\x2D\xC6"
+                         "\xE5\x6D\xCC\x74\x58\x37\x7A\xAC"
+                         "\x83\x8D\x00\x03\x22\x30\xF5\x3C"
+                         "\xE1\xF5\x70\x0C\x0F\xFB\x4D\x3B",
+       }, {
+               .plaintext = "abcdefghijklmnopqrstuvwxyz",
+               .psize  = 26,
+               .digest = "\xF1\xD7\x54\x66\x26\x36\xFF\xE9"
+                         "\x2C\x82\xEB\xB9\x21\x2A\x48\x4A"
+                         "\x8D\x38\x63\x1E\xAD\x42\x38\xF5"
+                         "\x44\x2E\xE1\x3B\x80\x54\xE4\x1B",
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                          "abcdefghijklmnopqrstuvwxyz0123456789",
+               .psize  = 62,
+               .digest = "\xDC\x37\xE0\x08\xCF\x9E\xE6\x9B"
+                         "\xF1\x1F\x00\xED\x9A\xBA\x26\x90"
+                         "\x1D\xD7\xC2\x8C\xDE\xC0\x66\xCC"
+                         "\x6A\xF4\x2E\x40\xF8\x2F\x3A\x1E",
+       }, {
+               .plaintext = "1234567890123456789012345678901234567890"
+                          "1234567890123456789012345678901234567890",
+               .psize  = 80,
+               .digest = "\x46\x6E\xF1\x8B\xAB\xB0\x15\x4D"
+                         "\x25\xB9\xD3\x8A\x64\x14\xF5\xC0"
+                         "\x87\x84\x37\x2B\xCC\xB2\x04\xD6"
+                         "\x54\x9C\x4A\xFA\xDB\x60\x14\x29",
+       }, {
+               .plaintext = "abcdbcdecdefdefgefghfghighijhijk",
+               .psize  = 32,
+               .digest = "\x2A\x98\x7E\xA4\x0F\x91\x70\x61"
+                         "\xF5\xD6\xF0\xA0\xE4\x64\x4F\x48"
+                         "\x8A\x7A\x5A\x52\xDE\xEE\x65\x62"
+                         "\x07\xC5\x62\xF9\x88\xE9\x5C\x69",
+       },
+};
+
+/*
+ * TIGER test vectors from Tiger website
+ */
+#define TGR192_TEST_VECTORS    6
+
+static struct hash_testvec tgr192_tv_template[] = {
+       {
+               .plaintext = "",
+               .psize  = 0,
+               .digest = "\x24\xf0\x13\x0c\x63\xac\x93\x32"
+                         "\x16\x16\x6e\x76\xb1\xbb\x92\x5f"
+                         "\xf3\x73\xde\x2d\x49\x58\x4e\x7a",
+       }, {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\xf2\x58\xc1\xe8\x84\x14\xab\x2a"
+                         "\x52\x7a\xb5\x41\xff\xc5\xb8\xbf"
+                         "\x93\x5f\x7b\x95\x1c\x13\x29\x51",
+       }, {
+               .plaintext = "Tiger",
+               .psize  = 5,
+               .digest = "\x9f\x00\xf5\x99\x07\x23\x00\xdd"
+                         "\x27\x6a\xbb\x38\xc8\xeb\x6d\xec"
+                         "\x37\x79\x0c\x11\x6f\x9d\x2b\xdf",
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
+               .psize  = 64,
+               .digest = "\x87\xfb\x2a\x90\x83\x85\x1c\xf7"
+                         "\x47\x0d\x2c\xf8\x10\xe6\xdf\x9e"
+                         "\xb5\x86\x44\x50\x34\xa5\xa3\x86",
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789",
+               .psize  = 64,
+               .digest = "\x46\x7d\xb8\x08\x63\xeb\xce\x48"
+                         "\x8d\xf1\xcd\x12\x61\x65\x5d\xe9"
+                         "\x57\x89\x65\x65\x97\x5f\x91\x97",
+       }, {
+               .plaintext = "Tiger - A Fast New Hash Function, "
+                          "by Ross Anderson and Eli Biham, "
+                          "proceedings of Fast Software Encryption 3, "
+                          "Cambridge, 1996.",
+               .psize  = 125,
+               .digest = "\x3d\x9a\xeb\x03\xd1\xbd\x1a\x63"
+                         "\x57\xb2\x77\x4d\xfd\x6d\x5b\x24"
+                         "\xdd\x68\x15\x1d\x50\x39\x74\xfc",
+       },
+};
+
+#define TGR160_TEST_VECTORS    6
+
+static struct hash_testvec tgr160_tv_template[] = {
+       {
+               .plaintext = "",
+               .psize  = 0,
+               .digest = "\x24\xf0\x13\x0c\x63\xac\x93\x32"
+                         "\x16\x16\x6e\x76\xb1\xbb\x92\x5f"
+                         "\xf3\x73\xde\x2d",
+       }, {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\xf2\x58\xc1\xe8\x84\x14\xab\x2a"
+                         "\x52\x7a\xb5\x41\xff\xc5\xb8\xbf"
+                         "\x93\x5f\x7b\x95",
+       }, {
+               .plaintext = "Tiger",
+               .psize  = 5,
+               .digest = "\x9f\x00\xf5\x99\x07\x23\x00\xdd"
+                         "\x27\x6a\xbb\x38\xc8\xeb\x6d\xec"
+                         "\x37\x79\x0c\x11",
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
+               .psize  = 64,
+               .digest = "\x87\xfb\x2a\x90\x83\x85\x1c\xf7"
+                         "\x47\x0d\x2c\xf8\x10\xe6\xdf\x9e"
+                         "\xb5\x86\x44\x50",
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789",
+               .psize  = 64,
+               .digest = "\x46\x7d\xb8\x08\x63\xeb\xce\x48"
+                         "\x8d\xf1\xcd\x12\x61\x65\x5d\xe9"
+                         "\x57\x89\x65\x65",
+       }, {
+               .plaintext = "Tiger - A Fast New Hash Function, "
+                          "by Ross Anderson and Eli Biham, "
+                          "proceedings of Fast Software Encryption 3, "
+                          "Cambridge, 1996.",
+               .psize  = 125,
+               .digest = "\x3d\x9a\xeb\x03\xd1\xbd\x1a\x63"
+                         "\x57\xb2\x77\x4d\xfd\x6d\x5b\x24"
+                         "\xdd\x68\x15\x1d",
+       },
+};
+
+#define TGR128_TEST_VECTORS    6
+
+static struct hash_testvec tgr128_tv_template[] = {
+       {
+               .plaintext = "",
+               .psize  = 0,
+               .digest = "\x24\xf0\x13\x0c\x63\xac\x93\x32"
+                         "\x16\x16\x6e\x76\xb1\xbb\x92\x5f",
+       }, {
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\xf2\x58\xc1\xe8\x84\x14\xab\x2a"
+                         "\x52\x7a\xb5\x41\xff\xc5\xb8\xbf",
+       }, {
+               .plaintext = "Tiger",
+               .psize  = 5,
+               .digest = "\x9f\x00\xf5\x99\x07\x23\x00\xdd"
+                         "\x27\x6a\xbb\x38\xc8\xeb\x6d\xec",
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
+               .psize  = 64,
+               .digest = "\x87\xfb\x2a\x90\x83\x85\x1c\xf7"
+                         "\x47\x0d\x2c\xf8\x10\xe6\xdf\x9e",
+       }, {
+               .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789",
+               .psize  = 64,
+               .digest = "\x46\x7d\xb8\x08\x63\xeb\xce\x48"
+                         "\x8d\xf1\xcd\x12\x61\x65\x5d\xe9",
+       }, {
+               .plaintext = "Tiger - A Fast New Hash Function, "
+                          "by Ross Anderson and Eli Biham, "
+                          "proceedings of Fast Software Encryption 3, "
+                          "Cambridge, 1996.",
+               .psize  = 125,
+               .digest = "\x3d\x9a\xeb\x03\xd1\xbd\x1a\x63"
+                         "\x57\xb2\x77\x4d\xfd\x6d\x5b\x24",
+       },
+};
+
+/*
+ * HMAC-MD5 test vectors from RFC2202
+ * (These need to be fixed to not use strlen).
+ */
+#define HMAC_MD5_TEST_VECTORS  7
+
+static struct hash_testvec hmac_md5_tv_template[] =
+{
+       {
+               .key    = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+               .ksize  = 16,
+               .plaintext = "Hi There",
+               .psize  = 8,
+               .digest = "\x92\x94\x72\x7a\x36\x38\xbb\x1c"
+                         "\x13\xf4\x8e\xf8\x15\x8b\xfc\x9d",
+       }, {
+               .key    = "Jefe",
+               .ksize  = 4,
+               .plaintext = "what do ya want for nothing?",
+               .psize  = 28,
+               .digest = "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03"
+                         "\xea\xa8\x6e\x31\x0a\x5d\xb7\x38",
+               .np     = 2,
+               .tap    = {14, 14}
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+               .ksize  = 16,
+               .plaintext = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
+               .psize  = 50,
+               .digest = "\x56\xbe\x34\x52\x1d\x14\x4c\x88"
+                         "\xdb\xb8\xc7\x33\xf0\xe8\xb3\xf6",
+       }, {
+               .key    = "\x01\x02\x03\x04\x05\x06\x07\x08"
+                         "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+                         "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+               .ksize  = 25,
+               .plaintext = "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
+               .psize  = 50,
+               .digest = "\x69\x7e\xaf\x0a\xca\x3a\x3a\xea"
+                         "\x3a\x75\x16\x47\x46\xff\xaa\x79",
+       }, {
+               .key    = "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c",
+               .ksize  = 16,
+               .plaintext = "Test With Truncation",
+               .psize  = 20,
+               .digest = "\x56\x46\x1e\xf2\x34\x2e\xdc\x00"
+                         "\xf9\xba\xb9\x95\x69\x0e\xfd\x4c",
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa",
+               .ksize  = 80,
+               .plaintext = "Test Using Larger Than Block-Size Key - Hash Key First",
+               .psize  = 54,
+               .digest = "\x6b\x1a\xb7\xfe\x4b\xd7\xbf\x8f"
+                         "\x0b\x62\xe6\xce\x61\xb9\xd0\xcd",
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa",
+               .ksize  = 80,
+               .plaintext = "Test Using Larger Than Block-Size Key and Larger Than One "
+                          "Block-Size Data",
+               .psize  = 73,
+               .digest = "\x6f\x63\x0f\xad\x67\xcd\xa0\xee"
+                         "\x1f\xb1\xf5\x62\xdb\x3a\xa5\x3e",
+       },
+};
+
+/*
+ * HMAC-RIPEMD128 test vectors from RFC2286
+ */
+#define HMAC_RMD128_TEST_VECTORS       7
+
+static struct hash_testvec hmac_rmd128_tv_template[] = {
+       {
+               .key    = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+               .ksize  = 16,
+               .plaintext = "Hi There",
+               .psize  = 8,
+               .digest = "\xfb\xf6\x1f\x94\x92\xaa\x4b\xbf"
+                         "\x81\xc1\x72\xe8\x4e\x07\x34\xdb",
+       }, {
+               .key    = "Jefe",
+               .ksize  = 4,
+               .plaintext = "what do ya want for nothing?",
+               .psize  = 28,
+               .digest = "\x87\x5f\x82\x88\x62\xb6\xb3\x34"
+                         "\xb4\x27\xc5\x5f\x9f\x7f\xf0\x9b",
+               .np     = 2,
+               .tap    = { 14, 14 },
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+               .ksize  = 16,
+               .plaintext = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
+               .psize  = 50,
+               .digest = "\x09\xf0\xb2\x84\x6d\x2f\x54\x3d"
+                         "\xa3\x63\xcb\xec\x8d\x62\xa3\x8d",
+       }, {
+               .key    = "\x01\x02\x03\x04\x05\x06\x07\x08"
+                         "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+                         "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+               .ksize  = 25,
+               .plaintext = "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
+               .psize  = 50,
+               .digest = "\xbd\xbb\xd7\xcf\x03\xe4\x4b\x5a"
+                         "\xa6\x0a\xf8\x15\xbe\x4d\x22\x94",
+       }, {
+               .key    = "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c",
+               .ksize  = 16,
+               .plaintext = "Test With Truncation",
+               .psize  = 20,
+               .digest = "\xe7\x98\x08\xf2\x4b\x25\xfd\x03"
+                         "\x1c\x15\x5f\x0d\x55\x1d\x9a\x3a",
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa",
+               .ksize  = 80,
+               .plaintext = "Test Using Larger Than Block-Size Key - Hash Key First",
+               .psize  = 54,
+               .digest = "\xdc\x73\x29\x28\xde\x98\x10\x4a"
+                         "\x1f\x59\xd3\x73\xc1\x50\xac\xbb",
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa",
+               .ksize  = 80,
+               .plaintext = "Test Using Larger Than Block-Size Key and Larger Than One "
+                          "Block-Size Data",
+               .psize  = 73,
+               .digest = "\x5c\x6b\xec\x96\x79\x3e\x16\xd4"
+                         "\x06\x90\xc2\x37\x63\x5f\x30\xc5",
+       },
+};
+
+/*
+ * HMAC-RIPEMD160 test vectors from RFC2286
+ */
+#define HMAC_RMD160_TEST_VECTORS       7
+
+static struct hash_testvec hmac_rmd160_tv_template[] = {
+       {
+               .key    = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+               .ksize  = 20,
+               .plaintext = "Hi There",
+               .psize  = 8,
+               .digest = "\x24\xcb\x4b\xd6\x7d\x20\xfc\x1a\x5d\x2e"
+                         "\xd7\x73\x2d\xcc\x39\x37\x7f\x0a\x56\x68",
+       }, {
+               .key    = "Jefe",
+               .ksize  = 4,
+               .plaintext = "what do ya want for nothing?",
+               .psize  = 28,
+               .digest = "\xdd\xa6\xc0\x21\x3a\x48\x5a\x9e\x24\xf4"
+                         "\x74\x20\x64\xa7\xf0\x33\xb4\x3c\x40\x69",
+               .np     = 2,
+               .tap    = { 14, 14 },
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+               .ksize  = 20,
+               .plaintext = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
+               .psize  = 50,
+               .digest = "\xb0\xb1\x05\x36\x0d\xe7\x59\x96\x0a\xb4"
+                         "\xf3\x52\x98\xe1\x16\xe2\x95\xd8\xe7\xc1",
+       }, {
+               .key    = "\x01\x02\x03\x04\x05\x06\x07\x08"
+                         "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+                         "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+               .ksize  = 25,
+               .plaintext = "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
+               .psize  = 50,
+               .digest = "\xd5\xca\x86\x2f\x4d\x21\xd5\xe6\x10\xe1"
+                         "\x8b\x4c\xf1\xbe\xb9\x7a\x43\x65\xec\xf4",
+       }, {
+               .key    = "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c",
+               .ksize  = 20,
+               .plaintext = "Test With Truncation",
+               .psize  = 20,
+               .digest = "\x76\x19\x69\x39\x78\xf9\x1d\x90\x53\x9a"
+                         "\xe7\x86\x50\x0f\xf3\xd8\xe0\x51\x8e\x39",
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa",
+               .ksize  = 80,
+               .plaintext = "Test Using Larger Than Block-Size Key - Hash Key First",
+               .psize  = 54,
+               .digest = "\x64\x66\xca\x07\xac\x5e\xac\x29\xe1\xbd"
+                         "\x52\x3e\x5a\xda\x76\x05\xb7\x91\xfd\x8b",
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa",
+               .ksize  = 80,
+               .plaintext = "Test Using Larger Than Block-Size Key and Larger Than One "
+                          "Block-Size Data",
+               .psize  = 73,
+               .digest = "\x69\xea\x60\x79\x8d\x71\x61\x6c\xce\x5f"
+                         "\xd0\x87\x1e\x23\x75\x4c\xd7\x5d\x5a\x0a",
+       },
+};
+
+/*
+ * HMAC-SHA1 test vectors from RFC2202
+ */
+#define HMAC_SHA1_TEST_VECTORS 7
+
+static struct hash_testvec hmac_sha1_tv_template[] = {
+       {
+               .key    = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+               .ksize  = 20,
+               .plaintext = "Hi There",
+               .psize  = 8,
+               .digest = "\xb6\x17\x31\x86\x55\x05\x72\x64"
+                         "\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1"
+                         "\x46\xbe",
+       }, {
+               .key    = "Jefe",
+               .ksize  = 4,
+               .plaintext = "what do ya want for nothing?",
+               .psize  = 28,
+               .digest = "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74"
+                         "\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79",
+               .np     = 2,
+               .tap    = { 14, 14 }
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+               .ksize  = 20,
+               .plaintext = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
+               .psize  = 50,
+               .digest = "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3"
+                         "\x9a\xf4\x8a\xa1\x7b\x4f\x63\xf1\x75\xd3",
+       }, {
+               .key    = "\x01\x02\x03\x04\x05\x06\x07\x08"
+                         "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+                         "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+               .ksize  = 25,
+               .plaintext = "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
+               .psize  = 50,
+               .digest = "\x4c\x90\x07\xf4\x02\x62\x50\xc6\xbc\x84"
+                         "\x14\xf9\xbf\x50\xc8\x6c\x2d\x72\x35\xda",
+       }, {
+               .key    = "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c",
+               .ksize  = 20,
+               .plaintext = "Test With Truncation",
+               .psize  = 20,
+               .digest = "\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2"
+                         "\x7b\xe1\xd5\x8b\xb9\x32\x4a\x9a\x5a\x04",
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa",
+               .ksize  = 80,
+               .plaintext = "Test Using Larger Than Block-Size Key - Hash Key First",
+               .psize  = 54,
+               .digest = "\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70"
+                         "\x56\x37\xce\x8a\x3b\x55\xed\x40\x21\x12",
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa",
+               .ksize  = 80,
+               .plaintext = "Test Using Larger Than Block-Size Key and Larger Than One "
+                          "Block-Size Data",
+               .psize  = 73,
+               .digest = "\xe8\xe9\x9d\x0f\x45\x23\x7d\x78\x6d\x6b"
+                         "\xba\xa7\x96\x5c\x78\x08\xbb\xff\x1a\x91",
+       },
+};
+
+
+/*
+ * SHA224 HMAC test vectors from RFC4231
+ */
+#define HMAC_SHA224_TEST_VECTORS    4
+
+static struct hash_testvec hmac_sha224_tv_template[] = {
+       {
+               .key    = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+                       "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+                       "\x0b\x0b\x0b\x0b",
+               .ksize  = 20,
+               /*  ("Hi There") */
+               .plaintext = "\x48\x69\x20\x54\x68\x65\x72\x65",
+               .psize  = 8,
+               .digest = "\x89\x6f\xb1\x12\x8a\xbb\xdf\x19"
+                       "\x68\x32\x10\x7c\xd4\x9d\xf3\x3f"
+                       "\x47\xb4\xb1\x16\x99\x12\xba\x4f"
+                       "\x53\x68\x4b\x22",
+       }, {
+               .key    = "Jefe",
+               .ksize  = 4,
+               /* ("what do ya want for nothing?") */
+               .plaintext = "\x77\x68\x61\x74\x20\x64\x6f\x20"
+                       "\x79\x61\x20\x77\x61\x6e\x74\x20"
+                       "\x66\x6f\x72\x20\x6e\x6f\x74\x68"
+                       "\x69\x6e\x67\x3f",
+               .psize  = 28,
+               .digest = "\xa3\x0e\x01\x09\x8b\xc6\xdb\xbf"
+                       "\x45\x69\x0f\x3a\x7e\x9e\x6d\x0f"
+                       "\x8b\xbe\xa2\xa3\x9e\x61\x48\x00"
+                       "\x8f\xd0\x5e\x44",
+               .np = 4,
+               .tap    = { 7, 7, 7, 7 }
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa",
+               .ksize  = 131,
+               /* ("Test Using Larger Than Block-Size Key - Hash Key First") */
+               .plaintext = "\x54\x65\x73\x74\x20\x55\x73\x69"
+                       "\x6e\x67\x20\x4c\x61\x72\x67\x65"
+                       "\x72\x20\x54\x68\x61\x6e\x20\x42"
+                       "\x6c\x6f\x63\x6b\x2d\x53\x69\x7a"
+                       "\x65\x20\x4b\x65\x79\x20\x2d\x20"
+                       "\x48\x61\x73\x68\x20\x4b\x65\x79"
+                       "\x20\x46\x69\x72\x73\x74",
+               .psize  = 54,
+               .digest = "\x95\xe9\xa0\xdb\x96\x20\x95\xad"
+                       "\xae\xbe\x9b\x2d\x6f\x0d\xbc\xe2"
+                       "\xd4\x99\xf1\x12\xf2\xd2\xb7\x27"
+                       "\x3f\xa6\x87\x0e",
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa",
+               .ksize  = 131,
+               /* ("This is a test using a larger than block-size key and a")
+               (" larger than block-size data. The key needs to be")
+                       (" hashed before being used by the HMAC algorithm.") */
+               .plaintext = "\x54\x68\x69\x73\x20\x69\x73\x20"
+                       "\x61\x20\x74\x65\x73\x74\x20\x75"
+                       "\x73\x69\x6e\x67\x20\x61\x20\x6c"
+                       "\x61\x72\x67\x65\x72\x20\x74\x68"
+                       "\x61\x6e\x20\x62\x6c\x6f\x63\x6b"
+                       "\x2d\x73\x69\x7a\x65\x20\x6b\x65"
+                       "\x79\x20\x61\x6e\x64\x20\x61\x20"
+                       "\x6c\x61\x72\x67\x65\x72\x20\x74"
+                       "\x68\x61\x6e\x20\x62\x6c\x6f\x63"
+                       "\x6b\x2d\x73\x69\x7a\x65\x20\x64"
+                       "\x61\x74\x61\x2e\x20\x54\x68\x65"
+                       "\x20\x6b\x65\x79\x20\x6e\x65\x65"
+                       "\x64\x73\x20\x74\x6f\x20\x62\x65"
+                       "\x20\x68\x61\x73\x68\x65\x64\x20"
+                       "\x62\x65\x66\x6f\x72\x65\x20\x62"
+                       "\x65\x69\x6e\x67\x20\x75\x73\x65"
+                       "\x64\x20\x62\x79\x20\x74\x68\x65"
+                       "\x20\x48\x4d\x41\x43\x20\x61\x6c"
+                       "\x67\x6f\x72\x69\x74\x68\x6d\x2e",
+               .psize  = 152,
+               .digest = "\x3a\x85\x41\x66\xac\x5d\x9f\x02"
+                       "\x3f\x54\xd5\x17\xd0\xb3\x9d\xbd"
+                       "\x94\x67\x70\xdb\x9c\x2b\x95\xc9"
+                       "\xf6\xf5\x65\xd1",
+       },
+};
+
+/*
+ * HMAC-SHA256 test vectors from
+ * draft-ietf-ipsec-ciph-sha-256-01.txt
+ */
+#define HMAC_SHA256_TEST_VECTORS       10
+
+static struct hash_testvec hmac_sha256_tv_template[] = {
+       {
+               .key    = "\x01\x02\x03\x04\x05\x06\x07\x08"
+                         "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+                         "\x11\x12\x13\x14\x15\x16\x17\x18"
+                         "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20",
+               .ksize  = 32,
+               .plaintext = "abc",
+               .psize  = 3,
+               .digest = "\xa2\x1b\x1f\x5d\x4c\xf4\xf7\x3a"
+                         "\x4d\xd9\x39\x75\x0f\x7a\x06\x6a"
+                         "\x7f\x98\xcc\x13\x1c\xb1\x6a\x66"
+                         "\x92\x75\x90\x21\xcf\xab\x81\x81",
+       }, {
+               .key    = "\x01\x02\x03\x04\x05\x06\x07\x08"
+                         "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+                         "\x11\x12\x13\x14\x15\x16\x17\x18"
+                         "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20",
+               .ksize  = 32,
+               .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+               .psize  = 56,
+               .digest = "\x10\x4f\xdc\x12\x57\x32\x8f\x08"
+                         "\x18\x4b\xa7\x31\x31\xc5\x3c\xae"
+                         "\xe6\x98\xe3\x61\x19\x42\x11\x49"
+                         "\xea\x8c\x71\x24\x56\x69\x7d\x30",
+       }, {
+               .key    = "\x01\x02\x03\x04\x05\x06\x07\x08"
+                         "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+                         "\x11\x12\x13\x14\x15\x16\x17\x18"
+                         "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20",
+               .ksize  = 32,
+               .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+                          "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+               .psize  = 112,
+               .digest = "\x47\x03\x05\xfc\x7e\x40\xfe\x34"
+                         "\xd3\xee\xb3\xe7\x73\xd9\x5a\xab"
+                         "\x73\xac\xf0\xfd\x06\x04\x47\xa5"
+                         "\xeb\x45\x95\xbf\x33\xa9\xd1\xa3",
+       }, {
+               .key    = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+                       "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+                       "\x0b\x0b\x0b\x0b\x0b\x0b",
+               .ksize  = 32,
+               .plaintext = "Hi There",
+               .psize  = 8,
+               .digest = "\x19\x8a\x60\x7e\xb4\x4b\xfb\xc6"
+                         "\x99\x03\xa0\xf1\xcf\x2b\xbd\xc5"
+                         "\xba\x0a\xa3\xf3\xd9\xae\x3c\x1c"
+                         "\x7a\x3b\x16\x96\xa0\xb6\x8c\xf7",
+       }, {
+               .key    = "Jefe",
+               .ksize  = 4,
+               .plaintext = "what do ya want for nothing?",
+               .psize  = 28,
+               .digest = "\x5b\xdc\xc1\x46\xbf\x60\x75\x4e"
+                         "\x6a\x04\x24\x26\x08\x95\x75\xc7"
+                         "\x5a\x00\x3f\x08\x9d\x27\x39\x83"
+                         "\x9d\xec\x58\xb9\x64\xec\x38\x43",
+               .np     = 2,
+               .tap    = { 14, 14 }
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+               .ksize  = 32,
+               .plaintext = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+                       "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
+               .psize  = 50,
+               .digest = "\xcd\xcb\x12\x20\xd1\xec\xcc\xea"
+                         "\x91\xe5\x3a\xba\x30\x92\xf9\x62"
+                         "\xe5\x49\xfe\x6c\xe9\xed\x7f\xdc"
+                         "\x43\x19\x1f\xbd\xe4\x5c\x30\xb0",
+       }, {
+               .key    = "\x01\x02\x03\x04\x05\x06\x07\x08"
+                         "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+                         "\x11\x12\x13\x14\x15\x16\x17\x18"
+                         "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
+                         "\x21\x22\x23\x24\x25",
+               .ksize  = 37,
+               .plaintext = "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+                       "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
+               .psize  = 50,
+               .digest = "\xd4\x63\x3c\x17\xf6\xfb\x8d\x74"
+                         "\x4c\x66\xde\xe0\xf8\xf0\x74\x55"
+                         "\x6e\xc4\xaf\x55\xef\x07\x99\x85"
+                         "\x41\x46\x8e\xb4\x9b\xd2\xe9\x17",
+       }, {
+               .key    = "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
+                       "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
+                       "\x0c\x0c\x0c\x0c\x0c\x0c",
+               .ksize  = 32,
+               .plaintext = "Test With Truncation",
+               .psize  = 20,
+               .digest = "\x75\x46\xaf\x01\x84\x1f\xc0\x9b"
+                         "\x1a\xb9\xc3\x74\x9a\x5f\x1c\x17"
+                         "\xd4\xf5\x89\x66\x8a\x58\x7b\x27"
+                         "\x00\xa9\xc9\x7c\x11\x93\xcf\x42",
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa",
+               .ksize  = 80,
+               .plaintext = "Test Using Larger Than Block-Size Key - Hash Key First",
+               .psize  = 54,
+               .digest = "\x69\x53\x02\x5e\xd9\x6f\x0c\x09"
+                         "\xf8\x0a\x96\xf7\x8e\x65\x38\xdb"
+                         "\xe2\xe7\xb8\x20\xe3\xdd\x97\x0e"
+                         "\x7d\xdd\x39\x09\x1b\x32\x35\x2f",
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa",
+               .ksize  = 80,
+               .plaintext = "Test Using Larger Than Block-Size Key and Larger Than "
+                          "One Block-Size Data",
+               .psize  = 73,
+               .digest = "\x63\x55\xac\x22\xe8\x90\xd0\xa3"
+                         "\xc8\x48\x1a\x5c\xa4\x82\x5b\xc8"
+                         "\x84\xd3\xe7\xa1\xff\x98\xa2\xfc"
+                         "\x2a\xc7\xd8\xe0\x64\xc3\xb2\xe6",
+       },
+};
+
+#define XCBC_AES_TEST_VECTORS 6
+
+static struct hash_testvec aes_xcbc128_tv_template[] = {
+       {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .plaintext = zeroed_string,
+               .digest = "\x75\xf0\x25\x1d\x52\x8a\xc0\x1c"
+                         "\x45\x73\xdf\xd5\x84\xd7\x9f\x29",
+               .psize  = 0,
+               .ksize  = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .plaintext = "\x00\x01\x02",
+               .digest = "\x5b\x37\x65\x80\xae\x2f\x19\xaf"
+                         "\xe7\x21\x9c\xee\xf1\x72\x75\x6f",
+               .psize  = 3,
+               .ksize  = 16,
+       } , {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .plaintext = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                            "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .digest = "\xd2\xa2\x46\xfa\x34\x9b\x68\xa7"
+                         "\x99\x98\xa4\x39\x4f\xf7\xa2\x63",
+               .psize  = 16,
+               .ksize  = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .plaintext = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                            "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                            "\x10\x11\x12\x13",
+               .digest = "\x47\xf5\x1b\x45\x64\x96\x62\x15"
+                         "\xb8\x98\x5c\x63\x05\x5e\xd3\x08",
+               .tap    = { 10, 10 },
+               .psize  = 20,
+               .np     = 2,
+               .ksize  = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .plaintext = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                            "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                            "\x10\x11\x12\x13\x14\x15\x16\x17"
+                            "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .digest = "\xf5\x4f\x0e\xc8\xd2\xb9\xf3\xd3"
+                         "\x68\x07\x73\x4b\xd5\x28\x3f\xd4",
+               .psize  = 32,
+               .ksize  = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .plaintext = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                            "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                            "\x10\x11\x12\x13\x14\x15\x16\x17"
+                            "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+                            "\x20\x21",
+               .digest = "\xbe\xcb\xb3\xbc\xcd\xb5\x18\xa3"
+                         "\x06\x77\xd5\x48\x1f\xb6\xb4\xd8",
+               .tap    = { 17, 17 },
+               .psize  = 34,
+               .np     = 2,
+               .ksize  = 16,
+       }
+};
+
+/*
+ * SHA384 HMAC test vectors from RFC4231
+ */
+
+#define HMAC_SHA384_TEST_VECTORS       4
+
+static struct hash_testvec hmac_sha384_tv_template[] = {
+       {
+               .key    = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+                         "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+                         "\x0b\x0b\x0b\x0b",
+               .ksize  = 20,
+               .plaintext = "Hi There",
+               .psize  = 8,
+               .digest = "\xaf\xd0\x39\x44\xd8\x48\x95\x62"
+                         "\x6b\x08\x25\xf4\xab\x46\x90\x7f"
+                         "\x15\xf9\xda\xdb\xe4\x10\x1e\xc6"
+                         "\x82\xaa\x03\x4c\x7c\xeb\xc5\x9c"
+                         "\xfa\xea\x9e\xa9\x07\x6e\xde\x7f"
+                         "\x4a\xf1\x52\xe8\xb2\xfa\x9c\xb6",
+       }, {
+               .key    = "Jefe",
+               .ksize  = 4,
+               .plaintext = "what do ya want for nothing?",
+               .psize  = 28,
+               .digest = "\xaf\x45\xd2\xe3\x76\x48\x40\x31"
+                         "\x61\x7f\x78\xd2\xb5\x8a\x6b\x1b"
+                         "\x9c\x7e\xf4\x64\xf5\xa0\x1b\x47"
+                         "\xe4\x2e\xc3\x73\x63\x22\x44\x5e"
+                         "\x8e\x22\x40\xca\x5e\x69\xe2\xc7"
+                         "\x8b\x32\x39\xec\xfa\xb2\x16\x49",
+               .np     = 4,
+               .tap    = { 7, 7, 7, 7 }
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa",
+               .ksize  = 131,
+               .plaintext = "Test Using Larger Than Block-Siz"
+                          "e Key - Hash Key First",
+               .psize  = 54,
+               .digest = "\x4e\xce\x08\x44\x85\x81\x3e\x90"
+                         "\x88\xd2\xc6\x3a\x04\x1b\xc5\xb4"
+                         "\x4f\x9e\xf1\x01\x2a\x2b\x58\x8f"
+                         "\x3c\xd1\x1f\x05\x03\x3a\xc4\xc6"
+                         "\x0c\x2e\xf6\xab\x40\x30\xfe\x82"
+                         "\x96\x24\x8d\xf1\x63\xf4\x49\x52",
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa",
+               .ksize  = 131,
+               .plaintext = "This is a test u"
+                          "sing a larger th"
+                          "an block-size ke"
+                          "y and a larger t"
+                          "han block-size d"
+                          "ata. The key nee"
+                          "ds to be hashed "
+                          "before being use"
+                          "d by the HMAC al"
+                          "gorithm.",
+               .psize  = 152,
+               .digest = "\x66\x17\x17\x8e\x94\x1f\x02\x0d"
+                         "\x35\x1e\x2f\x25\x4e\x8f\xd3\x2c"
+                         "\x60\x24\x20\xfe\xb0\xb8\xfb\x9a"
+                         "\xdc\xce\xbb\x82\x46\x1e\x99\xc5"
+                         "\xa6\x78\xcc\x31\xe7\x99\x17\x6d"
+                         "\x38\x60\xe6\x11\x0c\x46\x52\x3e",
+       },
+};
+
+/*
+ * SHA512 HMAC test vectors from RFC4231
+ */
+
+#define HMAC_SHA512_TEST_VECTORS       4
+
+static struct hash_testvec hmac_sha512_tv_template[] = {
+       {
+               .key    = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+                         "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+                         "\x0b\x0b\x0b\x0b",
+               .ksize  = 20,
+               .plaintext = "Hi There",
+               .psize  = 8,
+               .digest = "\x87\xaa\x7c\xde\xa5\xef\x61\x9d"
+                         "\x4f\xf0\xb4\x24\x1a\x1d\x6c\xb0"
+                         "\x23\x79\xf4\xe2\xce\x4e\xc2\x78"
+                         "\x7a\xd0\xb3\x05\x45\xe1\x7c\xde"
+                         "\xda\xa8\x33\xb7\xd6\xb8\xa7\x02"
+                         "\x03\x8b\x27\x4e\xae\xa3\xf4\xe4"
+                         "\xbe\x9d\x91\x4e\xeb\x61\xf1\x70"
+                         "\x2e\x69\x6c\x20\x3a\x12\x68\x54",
+       }, {
+               .key    = "Jefe",
+               .ksize  = 4,
+               .plaintext = "what do ya want for nothing?",
+               .psize  = 28,
+               .digest = "\x16\x4b\x7a\x7b\xfc\xf8\x19\xe2"
+                         "\xe3\x95\xfb\xe7\x3b\x56\xe0\xa3"
+                         "\x87\xbd\x64\x22\x2e\x83\x1f\xd6"
+                         "\x10\x27\x0c\xd7\xea\x25\x05\x54"
+                         "\x97\x58\xbf\x75\xc0\x5a\x99\x4a"
+                         "\x6d\x03\x4f\x65\xf8\xf0\xe6\xfd"
+                         "\xca\xea\xb1\xa3\x4d\x4a\x6b\x4b"
+                         "\x63\x6e\x07\x0a\x38\xbc\xe7\x37",
+               .np     = 4,
+               .tap    = { 7, 7, 7, 7 }
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                         "\xaa\xaa\xaa",
+               .ksize  = 131,
+               .plaintext = "Test Using Large"
+                          "r Than Block-Siz"
+                          "e Key - Hash Key"
+                          " First",
+               .psize  = 54,
+               .digest = "\x80\xb2\x42\x63\xc7\xc1\xa3\xeb"
+                       "\xb7\x14\x93\xc1\xdd\x7b\xe8\xb4"
+                       "\x9b\x46\xd1\xf4\x1b\x4a\xee\xc1"
+                       "\x12\x1b\x01\x37\x83\xf8\xf3\x52"
+                       "\x6b\x56\xd0\x37\xe0\x5f\x25\x98"
+                       "\xbd\x0f\xd2\x21\x5d\x6a\x1e\x52"
+                       "\x95\xe6\x4f\x73\xf6\x3f\x0a\xec"
+                       "\x8b\x91\x5a\x98\x5d\x78\x65\x98",
+       }, {
+               .key    = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+                       "\xaa\xaa\xaa",
+               .ksize  = 131,
+               .plaintext =
+                         "This is a test u"
+                         "sing a larger th"
+                         "an block-size ke"
+                         "y and a larger t"
+                         "han block-size d"
+                         "ata. The key nee"
+                         "ds to be hashed "
+                         "before being use"
+                         "d by the HMAC al"
+                         "gorithm.",
+               .psize  = 152,
+               .digest = "\xe3\x7b\x6a\x77\x5d\xc8\x7d\xba"
+                       "\xa4\xdf\xa9\xf9\x6e\x5e\x3f\xfd"
+                       "\xde\xbd\x71\xf8\x86\x72\x89\x86"
+                       "\x5d\xf5\xa3\x2d\x20\xcd\xc9\x44"
+                       "\xb6\x02\x2c\xac\x3c\x49\x82\xb1"
+                       "\x0d\x5e\xeb\x55\xc3\xe4\xde\x15"
+                       "\x13\x46\x76\xfb\x6d\xe0\x44\x60"
+                       "\x65\xc9\x74\x40\xfa\x8c\x6a\x58",
+       },
+};
+
+/*
+ * DES test vectors.
+ */
+#define DES_ENC_TEST_VECTORS           10
+#define DES_DEC_TEST_VECTORS           4
+#define DES_CBC_ENC_TEST_VECTORS       5
+#define DES_CBC_DEC_TEST_VECTORS       4
+#define DES3_EDE_ENC_TEST_VECTORS      3
+#define DES3_EDE_DEC_TEST_VECTORS      3
+#define DES3_EDE_CBC_ENC_TEST_VECTORS  1
+#define DES3_EDE_CBC_DEC_TEST_VECTORS  1
+
+static struct cipher_testvec des_enc_tv_template[] = {
+       { /* From Applied Cryptography */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xe7",
+               .ilen   = 8,
+               .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d",
+               .rlen   = 8,
+       }, { /* Same key, different plaintext block */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\x22\x33\x44\x55\x66\x77\x88\x99",
+               .ilen   = 8,
+               .result = "\xf7\x9c\x89\x2a\x33\x8f\x4a\x8b",
+               .rlen   = 8,
+       }, { /* Sbox test from NBS */
+               .key    = "\x7c\xa1\x10\x45\x4a\x1a\x6e\x57",
+               .klen   = 8,
+               .input  = "\x01\xa1\xd6\xd0\x39\x77\x67\x42",
+               .ilen   = 8,
+               .result = "\x69\x0f\x5b\x0d\x9a\x26\x93\x9b",
+               .rlen   = 8,
+       }, { /* Three blocks */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xe7"
+                         "\x22\x33\x44\x55\x66\x77\x88\x99"
+                         "\xca\xfe\xba\xbe\xfe\xed\xbe\xef",
+               .ilen   = 24,
+               .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d"
+                         "\xf7\x9c\x89\x2a\x33\x8f\x4a\x8b"
+                         "\xb4\x99\x26\xf7\x1f\xe1\xd4\x90",
+               .rlen   = 24,
+       }, { /* Weak key */
+               .fail   = 1,
+               .wk     = 1,
+               .key    = "\x01\x01\x01\x01\x01\x01\x01\x01",
+               .klen   = 8,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xe7",
+               .ilen   = 8,
+               .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d",
+               .rlen   = 8,
+       }, { /* Two blocks -- for testing encryption across pages */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xe7"
+                         "\x22\x33\x44\x55\x66\x77\x88\x99",
+               .ilen   = 16,
+               .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d"
+                         "\xf7\x9c\x89\x2a\x33\x8f\x4a\x8b",
+               .rlen   = 16,
+               .np     = 2,
+               .tap    = { 8, 8 }
+       }, { /* Four blocks -- for testing encryption with chunking */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xe7"
+                         "\x22\x33\x44\x55\x66\x77\x88\x99"
+                         "\xca\xfe\xba\xbe\xfe\xed\xbe\xef"
+                         "\x22\x33\x44\x55\x66\x77\x88\x99",
+               .ilen   = 32,
+               .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d"
+                         "\xf7\x9c\x89\x2a\x33\x8f\x4a\x8b"
+                         "\xb4\x99\x26\xf7\x1f\xe1\xd4\x90"
+                         "\xf7\x9c\x89\x2a\x33\x8f\x4a\x8b",
+               .rlen   = 32,
+               .np     = 3,
+               .tap    = { 14, 10, 8 }
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xe7"
+                         "\x22\x33\x44\x55\x66\x77\x88\x99"
+                         "\xca\xfe\xba\xbe\xfe\xed\xbe\xef",
+               .ilen   = 24,
+               .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d"
+                         "\xf7\x9c\x89\x2a\x33\x8f\x4a\x8b"
+                         "\xb4\x99\x26\xf7\x1f\xe1\xd4\x90",
+               .rlen   = 24,
+               .np     = 4,
+               .tap    = { 2, 1, 3, 18 }
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xe7"
+                         "\x22\x33\x44\x55\x66\x77\x88\x99",
+               .ilen   = 16,
+               .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d"
+                         "\xf7\x9c\x89\x2a\x33\x8f\x4a\x8b",
+               .rlen   = 16,
+               .np     = 5,
+               .tap    = { 2, 2, 2, 2, 8 }
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xe7",
+               .ilen   = 8,
+               .result = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d",
+               .rlen   = 8,
+               .np     = 8,
+               .tap    = { 1, 1, 1, 1, 1, 1, 1, 1 }
+       },
+};
+
+static struct cipher_testvec des_dec_tv_template[] = {
+       { /* From Applied Cryptography */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d",
+               .ilen   = 8,
+               .result = "\x01\x23\x45\x67\x89\xab\xcd\xe7",
+               .rlen   = 8,
+       }, { /* Sbox test from NBS */
+               .key    = "\x7c\xa1\x10\x45\x4a\x1a\x6e\x57",
+               .klen   = 8,
+               .input  = "\x69\x0f\x5b\x0d\x9a\x26\x93\x9b",
+               .ilen   = 8,
+               .result = "\x01\xa1\xd6\xd0\x39\x77\x67\x42",
+               .rlen   = 8,
+       }, { /* Two blocks, for chunking test */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d"
+                         "\x69\x0f\x5b\x0d\x9a\x26\x93\x9b",
+               .ilen   = 16,
+               .result = "\x01\x23\x45\x67\x89\xab\xcd\xe7"
+                         "\xa3\x99\x7b\xca\xaf\x69\xa0\xf5",
+               .rlen   = 16,
+               .np     = 2,
+               .tap    = { 8, 8 }
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\xc9\x57\x44\x25\x6a\x5e\xd3\x1d"
+                         "\x69\x0f\x5b\x0d\x9a\x26\x93\x9b",
+               .ilen   = 16,
+               .result = "\x01\x23\x45\x67\x89\xab\xcd\xe7"
+                         "\xa3\x99\x7b\xca\xaf\x69\xa0\xf5",
+               .rlen   = 16,
+               .np     = 3,
+               .tap    = { 3, 12, 1 }
+       },
+};
+
+static struct cipher_testvec des_cbc_enc_tv_template[] = {
+       { /* From OpenSSL */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .iv     = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .input  = "\x37\x36\x35\x34\x33\x32\x31\x20"
+                         "\x4e\x6f\x77\x20\x69\x73\x20\x74"
+                         "\x68\x65\x20\x74\x69\x6d\x65\x20",
+               .ilen   = 24,
+               .result = "\xcc\xd1\x73\xff\xab\x20\x39\xf4"
+                         "\xac\xd8\xae\xfd\xdf\xd8\xa1\xeb"
+                         "\x46\x8e\x91\x15\x78\x88\xba\x68",
+               .rlen   = 24,
+       }, { /* FIPS Pub 81 */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .iv     = "\x12\x34\x56\x78\x90\xab\xcd\xef",
+               .input  = "\x4e\x6f\x77\x20\x69\x73\x20\x74",
+               .ilen   = 8,
+               .result = "\xe5\xc7\xcd\xde\x87\x2b\xf2\x7c",
+               .rlen   = 8,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .iv     = "\xe5\xc7\xcd\xde\x87\x2b\xf2\x7c",
+               .input  = "\x68\x65\x20\x74\x69\x6d\x65\x20",
+               .ilen   = 8,
+               .result = "\x43\xe9\x34\x00\x8c\x38\x9c\x0f",
+               .rlen   = 8,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .iv     = "\x43\xe9\x34\x00\x8c\x38\x9c\x0f",
+               .input  = "\x66\x6f\x72\x20\x61\x6c\x6c\x20",
+               .ilen   = 8,
+               .result = "\x68\x37\x88\x49\x9a\x7c\x05\xf6",
+               .rlen   = 8,
+       }, { /* Copy of openssl vector for chunk testing */
+            /* From OpenSSL */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .iv     = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .input  = "\x37\x36\x35\x34\x33\x32\x31\x20"
+                         "\x4e\x6f\x77\x20\x69\x73\x20\x74"
+                         "\x68\x65\x20\x74\x69\x6d\x65\x20",
+               .ilen   = 24,
+               .result = "\xcc\xd1\x73\xff\xab\x20\x39\xf4"
+                         "\xac\xd8\xae\xfd\xdf\xd8\xa1\xeb"
+                         "\x46\x8e\x91\x15\x78\x88\xba\x68",
+               .rlen   = 24,
+               .np     = 2,
+               .tap    = { 13, 11 }
+       },
+};
+
+static struct cipher_testvec des_cbc_dec_tv_template[] = {
+       { /* FIPS Pub 81 */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .iv     = "\x12\x34\x56\x78\x90\xab\xcd\xef",
+               .input  = "\xe5\xc7\xcd\xde\x87\x2b\xf2\x7c",
+               .ilen   = 8,
+               .result = "\x4e\x6f\x77\x20\x69\x73\x20\x74",
+               .rlen   = 8,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .iv     = "\xe5\xc7\xcd\xde\x87\x2b\xf2\x7c",
+               .input  = "\x43\xe9\x34\x00\x8c\x38\x9c\x0f",
+               .ilen   = 8,
+               .result = "\x68\x65\x20\x74\x69\x6d\x65\x20",
+               .rlen   = 8,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .iv     = "\x43\xe9\x34\x00\x8c\x38\x9c\x0f",
+               .input  = "\x68\x37\x88\x49\x9a\x7c\x05\xf6",
+               .ilen   = 8,
+               .result = "\x66\x6f\x72\x20\x61\x6c\x6c\x20",
+               .rlen   = 8,
+       }, { /* Copy of above, for chunk testing */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .iv     = "\x43\xe9\x34\x00\x8c\x38\x9c\x0f",
+               .input  = "\x68\x37\x88\x49\x9a\x7c\x05\xf6",
+               .ilen   = 8,
+               .result = "\x66\x6f\x72\x20\x61\x6c\x6c\x20",
+               .rlen   = 8,
+               .np     = 2,
+               .tap    = { 4, 4 }
+       },
+};
+
+static struct cipher_testvec des3_ede_enc_tv_template[] = {
+       { /* These are from openssl */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\x55\x55\x55\x55\x55\x55\x55\x55"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .klen   = 24,
+               .input  = "\x73\x6f\x6d\x65\x64\x61\x74\x61",
+               .ilen   = 8,
+               .result = "\x18\xd7\x48\xe5\x63\x62\x05\x72",
+               .rlen   = 8,
+       }, {
+               .key    = "\x03\x52\x02\x07\x67\x20\x82\x17"
+                         "\x86\x02\x87\x66\x59\x08\x21\x98"
+                         "\x64\x05\x6a\xbd\xfe\xa9\x34\x57",
+               .klen   = 24,
+               .input  = "\x73\x71\x75\x69\x67\x67\x6c\x65",
+               .ilen   = 8,
+               .result = "\xc0\x7d\x2a\x0f\xa5\x66\xfa\x30",
+               .rlen   = 8,
+       }, {
+               .key    = "\x10\x46\x10\x34\x89\x98\x80\x20"
+                         "\x91\x07\xd0\x15\x89\x19\x01\x01"
+                         "\x19\x07\x92\x10\x98\x1a\x01\x01",
+               .klen   = 24,
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .ilen   = 8,
+               .result = "\xe1\xef\x62\xc3\x32\xfe\x82\x5b",
+               .rlen   = 8,
+       },
+};
+
+static struct cipher_testvec des3_ede_dec_tv_template[] = {
+       { /* These are from openssl */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\x55\x55\x55\x55\x55\x55\x55\x55"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .klen   = 24,
+               .input  = "\x18\xd7\x48\xe5\x63\x62\x05\x72",
+               .ilen   = 8,
+               .result = "\x73\x6f\x6d\x65\x64\x61\x74\x61",
+               .rlen   = 8,
+       }, {
+               .key    = "\x03\x52\x02\x07\x67\x20\x82\x17"
+                         "\x86\x02\x87\x66\x59\x08\x21\x98"
+                         "\x64\x05\x6a\xbd\xfe\xa9\x34\x57",
+               .klen   = 24,
+               .input  = "\xc0\x7d\x2a\x0f\xa5\x66\xfa\x30",
+               .ilen   = 8,
+               .result = "\x73\x71\x75\x69\x67\x67\x6c\x65",
+               .rlen   = 8,
+       }, {
+               .key    = "\x10\x46\x10\x34\x89\x98\x80\x20"
+                         "\x91\x07\xd0\x15\x89\x19\x01\x01"
+                         "\x19\x07\x92\x10\x98\x1a\x01\x01",
+               .klen   = 24,
+               .input  = "\xe1\xef\x62\xc3\x32\xfe\x82\x5b",
+               .ilen   = 8,
+               .result = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .rlen   = 8,
+       },
+};
+
+static struct cipher_testvec des3_ede_cbc_enc_tv_template[] = {
+       { /* Generated from openssl */
+               .key    = "\xE9\xC0\xFF\x2E\x76\x0B\x64\x24"
+                         "\x44\x4D\x99\x5A\x12\xD6\x40\xC0"
+                         "\xEA\xC2\x84\xE8\x14\x95\xDB\xE8",
+               .klen   = 24,
+               .iv     = "\x7D\x33\x88\x93\x0F\x93\xB2\x42",
+               .input  = "\x6f\x54\x20\x6f\x61\x4d\x79\x6e"
+                         "\x53\x20\x63\x65\x65\x72\x73\x74"
+                         "\x54\x20\x6f\x6f\x4d\x20\x6e\x61"
+                         "\x20\x79\x65\x53\x72\x63\x74\x65"
+                         "\x20\x73\x6f\x54\x20\x6f\x61\x4d"
+                         "\x79\x6e\x53\x20\x63\x65\x65\x72"
+                         "\x73\x74\x54\x20\x6f\x6f\x4d\x20"
+                         "\x6e\x61\x20\x79\x65\x53\x72\x63"
+                         "\x74\x65\x20\x73\x6f\x54\x20\x6f"
+                         "\x61\x4d\x79\x6e\x53\x20\x63\x65"
+                         "\x65\x72\x73\x74\x54\x20\x6f\x6f"
+                         "\x4d\x20\x6e\x61\x20\x79\x65\x53"
+                         "\x72\x63\x74\x65\x20\x73\x6f\x54"
+                         "\x20\x6f\x61\x4d\x79\x6e\x53\x20"
+                         "\x63\x65\x65\x72\x73\x74\x54\x20"
+                         "\x6f\x6f\x4d\x20\x6e\x61\x0a\x79",
+               .ilen   = 128,
+               .result = "\x0e\x2d\xb6\x97\x3c\x56\x33\xf4"
+                         "\x67\x17\x21\xc7\x6e\x8a\xd5\x49"
+                         "\x74\xb3\x49\x05\xc5\x1c\xd0\xed"
+                         "\x12\x56\x5c\x53\x96\xb6\x00\x7d"
+                         "\x90\x48\xfc\xf5\x8d\x29\x39\xcc"
+                         "\x8a\xd5\x35\x18\x36\x23\x4e\xd7"
+                         "\x76\xd1\xda\x0c\x94\x67\xbb\x04"
+                         "\x8b\xf2\x03\x6c\xa8\xcf\xb6\xea"
+                         "\x22\x64\x47\xaa\x8f\x75\x13\xbf"
+                         "\x9f\xc2\xc3\xf0\xc9\x56\xc5\x7a"
+                         "\x71\x63\x2e\x89\x7b\x1e\x12\xca"
+                         "\xe2\x5f\xaf\xd8\xa4\xf8\xc9\x7a"
+                         "\xd6\xf9\x21\x31\x62\x44\x45\xa6"
+                         "\xd6\xbc\x5a\xd3\x2d\x54\x43\xcc"
+                         "\x9d\xde\xa5\x70\xe9\x42\x45\x8a"
+                         "\x6b\xfa\xb1\x91\x13\xb0\xd9\x19",
+               .rlen   = 128,
+       },
+};
+
+static struct cipher_testvec des3_ede_cbc_dec_tv_template[] = {
+       { /* Generated from openssl */
+               .key    = "\xE9\xC0\xFF\x2E\x76\x0B\x64\x24"
+                         "\x44\x4D\x99\x5A\x12\xD6\x40\xC0"
+                         "\xEA\xC2\x84\xE8\x14\x95\xDB\xE8",
+               .klen   = 24,
+               .iv     = "\x7D\x33\x88\x93\x0F\x93\xB2\x42",
+               .input  = "\x0e\x2d\xb6\x97\x3c\x56\x33\xf4"
+                         "\x67\x17\x21\xc7\x6e\x8a\xd5\x49"
+                         "\x74\xb3\x49\x05\xc5\x1c\xd0\xed"
+                         "\x12\x56\x5c\x53\x96\xb6\x00\x7d"
+                         "\x90\x48\xfc\xf5\x8d\x29\x39\xcc"
+                         "\x8a\xd5\x35\x18\x36\x23\x4e\xd7"
+                         "\x76\xd1\xda\x0c\x94\x67\xbb\x04"
+                         "\x8b\xf2\x03\x6c\xa8\xcf\xb6\xea"
+                         "\x22\x64\x47\xaa\x8f\x75\x13\xbf"
+                         "\x9f\xc2\xc3\xf0\xc9\x56\xc5\x7a"
+                         "\x71\x63\x2e\x89\x7b\x1e\x12\xca"
+                         "\xe2\x5f\xaf\xd8\xa4\xf8\xc9\x7a"
+                         "\xd6\xf9\x21\x31\x62\x44\x45\xa6"
+                         "\xd6\xbc\x5a\xd3\x2d\x54\x43\xcc"
+                         "\x9d\xde\xa5\x70\xe9\x42\x45\x8a"
+                         "\x6b\xfa\xb1\x91\x13\xb0\xd9\x19",
+               .ilen   = 128,
+               .result = "\x6f\x54\x20\x6f\x61\x4d\x79\x6e"
+                         "\x53\x20\x63\x65\x65\x72\x73\x74"
+                         "\x54\x20\x6f\x6f\x4d\x20\x6e\x61"
+                         "\x20\x79\x65\x53\x72\x63\x74\x65"
+                         "\x20\x73\x6f\x54\x20\x6f\x61\x4d"
+                         "\x79\x6e\x53\x20\x63\x65\x65\x72"
+                         "\x73\x74\x54\x20\x6f\x6f\x4d\x20"
+                         "\x6e\x61\x20\x79\x65\x53\x72\x63"
+                         "\x74\x65\x20\x73\x6f\x54\x20\x6f"
+                         "\x61\x4d\x79\x6e\x53\x20\x63\x65"
+                         "\x65\x72\x73\x74\x54\x20\x6f\x6f"
+                         "\x4d\x20\x6e\x61\x20\x79\x65\x53"
+                         "\x72\x63\x74\x65\x20\x73\x6f\x54"
+                         "\x20\x6f\x61\x4d\x79\x6e\x53\x20"
+                         "\x63\x65\x65\x72\x73\x74\x54\x20"
+                         "\x6f\x6f\x4d\x20\x6e\x61\x0a\x79",
+               .rlen   = 128,
+       },
+};
+
+/*
+ * Blowfish test vectors.
+ */
+#define BF_ENC_TEST_VECTORS    6
+#define BF_DEC_TEST_VECTORS    6
+#define BF_CBC_ENC_TEST_VECTORS        1
+#define BF_CBC_DEC_TEST_VECTORS        1
+
+static struct cipher_testvec bf_enc_tv_template[] = {
+       { /* DES test vectors from OpenSSL */
+               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 8,
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .ilen   = 8,
+               .result = "\x4e\xf9\x97\x45\x61\x98\xdd\x78",
+               .rlen   = 8,
+       }, {
+               .key    = "\x1f\x1f\x1f\x1f\x0e\x0e\x0e\x0e",
+               .klen   = 8,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .ilen   = 8,
+               .result = "\xa7\x90\x79\x51\x08\xea\x3c\xae",
+               .rlen   = 8,
+       }, {
+               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+               .klen   = 8,
+               .input  = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .ilen   = 8,
+               .result = "\xe8\x7a\x24\x4e\x2c\xc8\x5e\x82",
+               .rlen   = 8,
+       }, { /* Vary the keylength... */
+               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87"
+                         "\x78\x69\x5a\x4b\x3c\x2d\x1e\x0f",
+               .klen   = 16,
+               .input  = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .ilen   = 8,
+               .result = "\x93\x14\x28\x87\xee\x3b\xe1\x5c",
+               .rlen   = 8,
+       }, {
+               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87"
+                         "\x78\x69\x5a\x4b\x3c\x2d\x1e\x0f"
+                         "\x00\x11\x22\x33\x44",
+               .klen   = 21,
+               .input  = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .ilen   = 8,
+               .result = "\xe6\xf5\x1e\xd7\x9b\x9d\xb2\x1f",
+               .rlen   = 8,
+       }, { /* Generated with bf488 */
+               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87"
+                         "\x78\x69\x5a\x4b\x3c\x2d\x1e\x0f"
+                         "\x00\x11\x22\x33\x44\x55\x66\x77"
+                         "\x04\x68\x91\x04\xc2\xfd\x3b\x2f"
+                         "\x58\x40\x23\x64\x1a\xba\x61\x76"
+                         "\x1f\x1f\x1f\x1f\x0e\x0e\x0e\x0e"
+                         "\xff\xff\xff\xff\xff\xff\xff\xff",
+               .klen   = 56,
+               .input  = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .ilen   = 8,
+               .result = "\xc0\x45\x04\x01\x2e\x4e\x1f\x53",
+               .rlen   = 8,
+       },
+};
+
+static struct cipher_testvec bf_dec_tv_template[] = {
+       { /* DES test vectors from OpenSSL */
+               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 8,
+               .input  = "\x4e\xf9\x97\x45\x61\x98\xdd\x78",
+               .ilen   = 8,
+               .result = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .rlen   = 8,
+       }, {
+               .key    = "\x1f\x1f\x1f\x1f\x0e\x0e\x0e\x0e",
+               .klen   = 8,
+               .input  = "\xa7\x90\x79\x51\x08\xea\x3c\xae",
+               .ilen   = 8,
+               .result = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .rlen   = 8,
+       }, {
+               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+               .klen   = 8,
+               .input  = "\xe8\x7a\x24\x4e\x2c\xc8\x5e\x82",
+               .ilen   = 8,
+               .result = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .rlen   = 8,
+       }, { /* Vary the keylength... */
+               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87"
+                         "\x78\x69\x5a\x4b\x3c\x2d\x1e\x0f",
+               .klen   = 16,
+               .input  = "\x93\x14\x28\x87\xee\x3b\xe1\x5c",
+               .ilen   = 8,
+               .result = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .rlen   = 8,
+       }, {
+               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87"
+                         "\x78\x69\x5a\x4b\x3c\x2d\x1e\x0f"
+                         "\x00\x11\x22\x33\x44",
+               .klen   = 21,
+               .input  = "\xe6\xf5\x1e\xd7\x9b\x9d\xb2\x1f",
+               .ilen   = 8,
+               .result = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .rlen   = 8,
+       }, { /* Generated with bf488, using OpenSSL, Libgcrypt and Nettle */
+               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87"
+                         "\x78\x69\x5a\x4b\x3c\x2d\x1e\x0f"
+                         "\x00\x11\x22\x33\x44\x55\x66\x77"
+                         "\x04\x68\x91\x04\xc2\xfd\x3b\x2f"
+                         "\x58\x40\x23\x64\x1a\xba\x61\x76"
+                         "\x1f\x1f\x1f\x1f\x0e\x0e\x0e\x0e"
+                         "\xff\xff\xff\xff\xff\xff\xff\xff",
+               .klen   = 56,
+               .input  = "\xc0\x45\x04\x01\x2e\x4e\x1f\x53",
+               .ilen   = 8,
+               .result = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .rlen   = 8,
+       },
+};
+
+static struct cipher_testvec bf_cbc_enc_tv_template[] = {
+       { /* From OpenSSL */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+               .klen   = 16,
+               .iv     = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .input  = "\x37\x36\x35\x34\x33\x32\x31\x20"
+                         "\x4e\x6f\x77\x20\x69\x73\x20\x74"
+                         "\x68\x65\x20\x74\x69\x6d\x65\x20"
+                         "\x66\x6f\x72\x20\x00\x00\x00\x00",
+               .ilen   = 32,
+               .result = "\x6b\x77\xb4\xd6\x30\x06\xde\xe6"
+                         "\x05\xb1\x56\xe2\x74\x03\x97\x93"
+                         "\x58\xde\xb9\xe7\x15\x46\x16\xd9"
+                         "\x59\xf1\x65\x2b\xd5\xff\x92\xcc",
+               .rlen   = 32,
+       },
+};
+
+static struct cipher_testvec bf_cbc_dec_tv_template[] = {
+       { /* From OpenSSL */
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+               .klen   = 16,
+               .iv     = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .input  = "\x6b\x77\xb4\xd6\x30\x06\xde\xe6"
+                         "\x05\xb1\x56\xe2\x74\x03\x97\x93"
+                         "\x58\xde\xb9\xe7\x15\x46\x16\xd9"
+                         "\x59\xf1\x65\x2b\xd5\xff\x92\xcc",
+               .ilen   = 32,
+               .result = "\x37\x36\x35\x34\x33\x32\x31\x20"
+                         "\x4e\x6f\x77\x20\x69\x73\x20\x74"
+                         "\x68\x65\x20\x74\x69\x6d\x65\x20"
+                         "\x66\x6f\x72\x20\x00\x00\x00\x00",
+               .rlen   = 32,
+       },
+};
+
+/*
+ * Twofish test vectors.
+ */
+#define TF_ENC_TEST_VECTORS            3
+#define TF_DEC_TEST_VECTORS            3
+#define TF_CBC_ENC_TEST_VECTORS                4
+#define TF_CBC_DEC_TEST_VECTORS                4
+
+static struct cipher_testvec tf_enc_tv_template[] = {
+       {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .input  = zeroed_string,
+               .ilen   = 16,
+               .result = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
+                         "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a",
+               .rlen   = 16,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10"
+                         "\x00\x11\x22\x33\x44\x55\x66\x77",
+               .klen   = 24,
+               .input  = zeroed_string,
+               .ilen   = 16,
+               .result = "\xcf\xd1\xd2\xe5\xa9\xbe\x9c\xdf"
+                         "\x50\x1f\x13\xb8\x92\xbd\x22\x48",
+               .rlen   = 16,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10"
+                         "\x00\x11\x22\x33\x44\x55\x66\x77"
+                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+               .klen   = 32,
+               .input  = zeroed_string,
+               .ilen   = 16,
+               .result = "\x37\x52\x7b\xe0\x05\x23\x34\xb8"
+                         "\x9f\x0c\xfc\xca\xe8\x7c\xfa\x20",
+               .rlen   = 16,
+       },
+};
+
+static struct cipher_testvec tf_dec_tv_template[] = {
+       {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .input  = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
+                         "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a",
+               .ilen   = 16,
+               .result = zeroed_string,
+               .rlen   = 16,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10"
+                         "\x00\x11\x22\x33\x44\x55\x66\x77",
+               .klen   = 24,
+               .input  = "\xcf\xd1\xd2\xe5\xa9\xbe\x9c\xdf"
+                         "\x50\x1f\x13\xb8\x92\xbd\x22\x48",
+               .ilen   = 16,
+               .result = zeroed_string,
+               .rlen   = 16,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10"
+                         "\x00\x11\x22\x33\x44\x55\x66\x77"
+                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+               .klen   = 32,
+               .input  = "\x37\x52\x7b\xe0\x05\x23\x34\xb8"
+                         "\x9f\x0c\xfc\xca\xe8\x7c\xfa\x20",
+               .ilen   = 16,
+               .result = zeroed_string,
+               .rlen   = 16,
+       },
+};
+
+static struct cipher_testvec tf_cbc_enc_tv_template[] = {
+       { /* Generated with Nettle */
+               .key    = zeroed_string,
+               .klen   = 16,
+               .iv     = zeroed_string,
+               .input  = zeroed_string,
+               .ilen   = 16,
+               .result = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
+                         "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a",
+               .rlen   = 16,
+       }, {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .iv     = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
+                         "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a",
+               .input  = zeroed_string,
+               .ilen   = 16,
+               .result = "\xd4\x91\xdb\x16\xe7\xb1\xc3\x9e"
+                         "\x86\xcb\x08\x6b\x78\x9f\x54\x19",
+               .rlen   = 16,
+       }, {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .iv     = "\xd4\x91\xdb\x16\xe7\xb1\xc3\x9e"
+                         "\x86\xcb\x08\x6b\x78\x9f\x54\x19",
+               .input  = zeroed_string,
+               .ilen   = 16,
+               .result = "\x05\xef\x8c\x61\xa8\x11\x58\x26"
+                         "\x34\xba\x5c\xb7\x10\x6a\xa6\x41",
+               .rlen   = 16,
+       }, {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .iv     = zeroed_string,
+               .input  = zeroed_string,
+               .ilen   = 48,
+               .result = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
+                         "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a"
+                         "\xd4\x91\xdb\x16\xe7\xb1\xc3\x9e"
+                         "\x86\xcb\x08\x6b\x78\x9f\x54\x19"
+                         "\x05\xef\x8c\x61\xa8\x11\x58\x26"
+                         "\x34\xba\x5c\xb7\x10\x6a\xa6\x41",
+               .rlen   = 48,
+       },
+};
+
+static struct cipher_testvec tf_cbc_dec_tv_template[] = {
+       { /* Reverse of the first four above */
+               .key    = zeroed_string,
+               .klen   = 16,
+               .iv     = zeroed_string,
+               .input  = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
+                         "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a",
+               .ilen   = 16,
+               .result = zeroed_string,
+               .rlen   = 16,
+       }, {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .iv     = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
+                         "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a",
+               .input  = "\xd4\x91\xdb\x16\xe7\xb1\xc3\x9e"
+                         "\x86\xcb\x08\x6b\x78\x9f\x54\x19",
+               .ilen   = 16,
+               .result = zeroed_string,
+               .rlen   = 16,
+       }, {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .iv     = "\xd4\x91\xdb\x16\xe7\xb1\xc3\x9e"
+                         "\x86\xcb\x08\x6b\x78\x9f\x54\x19",
+               .input  = "\x05\xef\x8c\x61\xa8\x11\x58\x26"
+                         "\x34\xba\x5c\xb7\x10\x6a\xa6\x41",
+               .ilen   = 16,
+               .result = zeroed_string,
+               .rlen   = 16,
+       }, {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .iv     = zeroed_string,
+               .input  = "\x9f\x58\x9f\x5c\xf6\x12\x2c\x32"
+                         "\xb6\xbf\xec\x2f\x2a\xe8\xc3\x5a"
+                         "\xd4\x91\xdb\x16\xe7\xb1\xc3\x9e"
+                         "\x86\xcb\x08\x6b\x78\x9f\x54\x19"
+                         "\x05\xef\x8c\x61\xa8\x11\x58\x26"
+                         "\x34\xba\x5c\xb7\x10\x6a\xa6\x41",
+               .ilen   = 48,
+               .result = zeroed_string,
+               .rlen   = 48,
+       },
+};
+
+/*
+ * Serpent test vectors.  These are backwards because Serpent writes
+ * octet sequences in right-to-left mode.
+ */
+#define SERPENT_ENC_TEST_VECTORS       4
+#define SERPENT_DEC_TEST_VECTORS       4
+
+#define TNEPRES_ENC_TEST_VECTORS       4
+#define TNEPRES_DEC_TEST_VECTORS       4
+
+static struct cipher_testvec serpent_enc_tv_template[] = {
+       {
+               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .ilen   = 16,
+               .result = "\x12\x07\xfc\xce\x9b\xd0\xd6\x47"
+                         "\x6a\xe9\x8f\xbe\xd1\x43\xa0\xe2",
+               .rlen   = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .klen   = 16,
+               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .ilen   = 16,
+               .result = "\x4c\x7d\x8a\x32\x80\x72\xa2\x2c"
+                         "\x82\x3e\x4a\x1f\x3a\xcd\xa1\x6d",
+               .rlen   = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .klen   = 32,
+               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .ilen   = 16,
+               .result = "\xde\x26\x9f\xf8\x33\xe4\x32\xb8"
+                         "\x5b\x2e\x88\xd2\x70\x1c\xe7\x5c",
+               .rlen   = 16,
+       }, {
+               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80",
+               .klen   = 16,
+               .input  = zeroed_string,
+               .ilen   = 16,
+               .result = "\xdd\xd2\x6b\x98\xa5\xff\xd8\x2c"
+                         "\x05\x34\x5a\x9d\xad\xbf\xaf\x49",
+               .rlen   = 16,
+       },
+};
+
+static struct cipher_testvec tnepres_enc_tv_template[] = {
+       { /* KeySize=128, PT=0, I=1 */
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .key    = "\x80\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 16,
+               .ilen   = 16,
+               .result = "\x49\xaf\xbf\xad\x9d\x5a\x34\x05"
+                         "\x2c\xd8\xff\xa5\x98\x6b\xd2\xdd",
+               .rlen   = 16,
+       }, { /* KeySize=192, PT=0, I=1 */
+               .key    = "\x80\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 24,
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .ilen   = 16,
+               .result = "\xe7\x8e\x54\x02\xc7\x19\x55\x68"
+                         "\xac\x36\x78\xf7\xa3\xf6\x0c\x66",
+               .rlen   = 16,
+       }, { /* KeySize=256, PT=0, I=1 */
+               .key    = "\x80\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 32,
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .ilen   = 16,
+               .result = "\xab\xed\x96\xe7\x66\xbf\x28\xcb"
+                         "\xc0\xeb\xd2\x1a\x82\xef\x08\x19",
+               .rlen   = 16,
+       }, { /* KeySize=256, I=257 */
+               .key    = "\x1f\x1e\x1d\x1c\x1b\x1a\x19\x18"
+                         "\x17\x16\x15\x14\x13\x12\x11\x10"
+                         "\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08"
+                         "\x07\x06\x05\x04\x03\x02\x01\x00",
+               .klen   = 32,
+               .input  = "\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08"
+                         "\x07\x06\x05\x04\x03\x02\x01\x00",
+               .ilen   = 16,
+               .result = "\x5c\xe7\x1c\x70\xd2\x88\x2e\x5b"
+                         "\xb8\x32\xe4\x33\xf8\x9f\x26\xde",
+               .rlen   = 16,
+       },
+};
+
+
+static struct cipher_testvec serpent_dec_tv_template[] = {
+       {
+               .input  = "\x12\x07\xfc\xce\x9b\xd0\xd6\x47"
+                         "\x6a\xe9\x8f\xbe\xd1\x43\xa0\xe2",
+               .ilen   = 16,
+               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .rlen   = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .klen   = 16,
+               .input  = "\x4c\x7d\x8a\x32\x80\x72\xa2\x2c"
+                         "\x82\x3e\x4a\x1f\x3a\xcd\xa1\x6d",
+               .ilen   = 16,
+               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .rlen   = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .klen   = 32,
+               .input  = "\xde\x26\x9f\xf8\x33\xe4\x32\xb8"
+                         "\x5b\x2e\x88\xd2\x70\x1c\xe7\x5c",
+               .ilen   = 16,
+               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .rlen   = 16,
+       }, {
+               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80",
+               .klen   = 16,
+               .input  = "\xdd\xd2\x6b\x98\xa5\xff\xd8\x2c"
+                         "\x05\x34\x5a\x9d\xad\xbf\xaf\x49",
+               .ilen   = 16,
+               .result = zeroed_string,
+               .rlen   = 16,
+       },
+};
+
+static struct cipher_testvec tnepres_dec_tv_template[] = {
+       {
+               .input  = "\x41\xcc\x6b\x31\x59\x31\x45\x97"
+                         "\x6d\x6f\xbb\x38\x4b\x37\x21\x28",
+               .ilen   = 16,
+               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .rlen   = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .klen   = 16,
+               .input  = "\xea\xf4\xd7\xfc\xd8\x01\x34\x47"
+                         "\x81\x45\x0b\xfa\x0c\xd6\xad\x6e",
+               .ilen   = 16,
+               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .rlen   = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .klen   = 32,
+               .input  = "\x64\xa9\x1a\x37\xed\x9f\xe7\x49"
+                         "\xa8\x4e\x76\xd6\xf5\x0d\x78\xee",
+               .ilen   = 16,
+               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .rlen   = 16,
+       }, { /* KeySize=128, I=121 */
+               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80",
+               .klen   = 16,
+               .input  = "\x3d\xda\xbf\xc0\x06\xda\xab\x06"
+                         "\x46\x2a\xf4\xef\x81\x54\x4e\x26",
+               .ilen   = 16,
+               .result = zeroed_string,
+               .rlen   = 16,
+       },
+};
+
+
+/* Cast6 test vectors from RFC 2612 */
+#define CAST6_ENC_TEST_VECTORS 3
+#define CAST6_DEC_TEST_VECTORS  3
+
+static struct cipher_testvec cast6_enc_tv_template[] = {
+       {
+               .key    = "\x23\x42\xbb\x9e\xfa\x38\x54\x2c"
+                         "\x0a\xf7\x56\x47\xf2\x9f\x61\x5d",
+               .klen   = 16,
+               .input  = zeroed_string,
+               .ilen   = 16,
+               .result = "\xc8\x42\xa0\x89\x72\xb4\x3d\x20"
+                         "\x83\x6c\x91\xd1\xb7\x53\x0f\x6b",
+               .rlen   = 16,
+       }, {
+               .key    = "\x23\x42\xbb\x9e\xfa\x38\x54\x2c"
+                         "\xbe\xd0\xac\x83\x94\x0a\xc2\x98"
+                         "\xba\xc7\x7a\x77\x17\x94\x28\x63",
+               .klen   = 24,
+               .input  = zeroed_string,
+               .ilen   = 16,
+               .result = "\x1b\x38\x6c\x02\x10\xdc\xad\xcb"
+                         "\xdd\x0e\x41\xaa\x08\xa7\xa7\xe8",
+               .rlen   = 16,
+       }, {
+               .key    = "\x23\x42\xbb\x9e\xfa\x38\x54\x2c"
+                         "\xbe\xd0\xac\x83\x94\x0a\xc2\x98"
+                         "\x8d\x7c\x47\xce\x26\x49\x08\x46"
+                         "\x1c\xc1\xb5\x13\x7a\xe6\xb6\x04",
+               .klen   = 32,
+               .input  = zeroed_string,
+               .ilen   = 16,
+               .result = "\x4f\x6a\x20\x38\x28\x68\x97\xb9"
+                         "\xc9\x87\x01\x36\x55\x33\x17\xfa",
+               .rlen   = 16,
+       },
+};
+
+static struct cipher_testvec cast6_dec_tv_template[] = {
+       {
+               .key    = "\x23\x42\xbb\x9e\xfa\x38\x54\x2c"
+                         "\x0a\xf7\x56\x47\xf2\x9f\x61\x5d",
+               .klen   = 16,
+               .input  = "\xc8\x42\xa0\x89\x72\xb4\x3d\x20"
+                         "\x83\x6c\x91\xd1\xb7\x53\x0f\x6b",
+               .ilen   = 16,
+               .result = zeroed_string,
+               .rlen   = 16,
+       }, {
+               .key    = "\x23\x42\xbb\x9e\xfa\x38\x54\x2c"
+                         "\xbe\xd0\xac\x83\x94\x0a\xc2\x98"
+                         "\xba\xc7\x7a\x77\x17\x94\x28\x63",
+               .klen   = 24,
+               .input  = "\x1b\x38\x6c\x02\x10\xdc\xad\xcb"
+                         "\xdd\x0e\x41\xaa\x08\xa7\xa7\xe8",
+               .ilen   = 16,
+               .result = zeroed_string,
+               .rlen   = 16,
+       }, {
+               .key    = "\x23\x42\xbb\x9e\xfa\x38\x54\x2c"
+                         "\xbe\xd0\xac\x83\x94\x0a\xc2\x98"
+                         "\x8d\x7c\x47\xce\x26\x49\x08\x46"
+                         "\x1c\xc1\xb5\x13\x7a\xe6\xb6\x04",
+               .klen   = 32,
+               .input  = "\x4f\x6a\x20\x38\x28\x68\x97\xb9"
+                         "\xc9\x87\x01\x36\x55\x33\x17\xfa",
+               .ilen   = 16,
+               .result = zeroed_string,
+               .rlen   = 16,
+       },
+};
+
+
+/*
+ * AES test vectors.
+ */
+#define AES_ENC_TEST_VECTORS 3
+#define AES_DEC_TEST_VECTORS 3
+#define AES_CBC_ENC_TEST_VECTORS 4
+#define AES_CBC_DEC_TEST_VECTORS 4
+#define AES_LRW_ENC_TEST_VECTORS 8
+#define AES_LRW_DEC_TEST_VECTORS 8
+#define AES_XTS_ENC_TEST_VECTORS 4
+#define AES_XTS_DEC_TEST_VECTORS 4
+#define AES_CTR_ENC_TEST_VECTORS 7
+#define AES_CTR_DEC_TEST_VECTORS 6
+#define AES_GCM_ENC_TEST_VECTORS 9
+#define AES_GCM_DEC_TEST_VECTORS 8
+#define AES_CCM_ENC_TEST_VECTORS 7
+#define AES_CCM_DEC_TEST_VECTORS 7
+
+static struct cipher_testvec aes_enc_tv_template[] = {
+       { /* From FIPS-197 */
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .klen   = 16,
+               .input  = "\x00\x11\x22\x33\x44\x55\x66\x77"
+                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+               .ilen   = 16,
+               .result = "\x69\xc4\xe0\xd8\x6a\x7b\x04\x30"
+                         "\xd8\xcd\xb7\x80\x70\xb4\xc5\x5a",
+               .rlen   = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17",
+               .klen   = 24,
+               .input  = "\x00\x11\x22\x33\x44\x55\x66\x77"
+                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+               .ilen   = 16,
+               .result = "\xdd\xa9\x7c\xa4\x86\x4c\xdf\xe0"
+                         "\x6e\xaf\x70\xa0\xec\x0d\x71\x91",
+               .rlen   = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .klen   = 32,
+               .input  = "\x00\x11\x22\x33\x44\x55\x66\x77"
+                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+               .ilen   = 16,
+               .result = "\x8e\xa2\xb7\xca\x51\x67\x45\xbf"
+                         "\xea\xfc\x49\x90\x4b\x49\x60\x89",
+               .rlen   = 16,
+       },
+};
+
+static struct cipher_testvec aes_dec_tv_template[] = {
+       { /* From FIPS-197 */
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .klen   = 16,
+               .input  = "\x69\xc4\xe0\xd8\x6a\x7b\x04\x30"
+                         "\xd8\xcd\xb7\x80\x70\xb4\xc5\x5a",
+               .ilen   = 16,
+               .result = "\x00\x11\x22\x33\x44\x55\x66\x77"
+                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+               .rlen   = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17",
+               .klen   = 24,
+               .input  = "\xdd\xa9\x7c\xa4\x86\x4c\xdf\xe0"
+                         "\x6e\xaf\x70\xa0\xec\x0d\x71\x91",
+               .ilen   = 16,
+               .result = "\x00\x11\x22\x33\x44\x55\x66\x77"
+                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+               .rlen   = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .klen   = 32,
+               .input  = "\x8e\xa2\xb7\xca\x51\x67\x45\xbf"
+                         "\xea\xfc\x49\x90\x4b\x49\x60\x89",
+               .ilen   = 16,
+               .result = "\x00\x11\x22\x33\x44\x55\x66\x77"
+                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+               .rlen   = 16,
+       },
+};
+
+static struct cipher_testvec aes_cbc_enc_tv_template[] = {
+       { /* From RFC 3602 */
+               .key    = "\x06\xa9\x21\x40\x36\xb8\xa1\x5b"
+                         "\x51\x2e\x03\xd5\x34\x12\x00\x06",
+               .klen   = 16,
+               .iv     = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30"
+                         "\xb4\x22\xda\x80\x2c\x9f\xac\x41",
+               .input  = "Single block msg",
+               .ilen   = 16,
+               .result = "\xe3\x53\x77\x9c\x10\x79\xae\xb8"
+                         "\x27\x08\x94\x2d\xbe\x77\x18\x1a",
+               .rlen   = 16,
+       }, {
+               .key    = "\xc2\x86\x69\x6d\x88\x7c\x9a\xa0"
+                         "\x61\x1b\xbb\x3e\x20\x25\xa4\x5a",
+               .klen   = 16,
+               .iv     = "\x56\x2e\x17\x99\x6d\x09\x3d\x28"
+                         "\xdd\xb3\xba\x69\x5a\x2e\x6f\x58",
+               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .ilen   = 32,
+               .result = "\xd2\x96\xcd\x94\xc2\xcc\xcf\x8a"
+                         "\x3a\x86\x30\x28\xb5\xe1\xdc\x0a"
+                         "\x75\x86\x60\x2d\x25\x3c\xff\xf9"
+                         "\x1b\x82\x66\xbe\xa6\xd6\x1a\xb1",
+               .rlen   = 32,
+       }, { /* From NIST SP800-38A */
+               .key    = "\x8e\x73\xb0\xf7\xda\x0e\x64\x52"
+                         "\xc8\x10\xf3\x2b\x80\x90\x79\xe5"
+                         "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
+               .klen   = 24,
+               .iv     = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .input  = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+                         "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+                         "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+                         "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+                         "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+                         "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+                         "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+                         "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+               .ilen   = 64,
+               .result = "\x4f\x02\x1d\xb2\x43\xbc\x63\x3d"
+                         "\x71\x78\x18\x3a\x9f\xa0\x71\xe8"
+                         "\xb4\xd9\xad\xa9\xad\x7d\xed\xf4"
+                         "\xe5\xe7\x38\x76\x3f\x69\x14\x5a"
+                         "\x57\x1b\x24\x20\x12\xfb\x7a\xe0"
+                         "\x7f\xa9\xba\xac\x3d\xf1\x02\xe0"
+                         "\x08\xb0\xe2\x79\x88\x59\x88\x81"
+                         "\xd9\x20\xa9\xe6\x4f\x56\x15\xcd",
+               .rlen   = 64,
+       }, {
+               .key    = "\x60\x3d\xeb\x10\x15\xca\x71\xbe"
+                         "\x2b\x73\xae\xf0\x85\x7d\x77\x81"
+                         "\x1f\x35\x2c\x07\x3b\x61\x08\xd7"
+                         "\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
+               .klen   = 32,
+               .iv     = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .input  = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+                         "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+                         "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+                         "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+                         "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+                         "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+                         "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+                         "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+               .ilen   = 64,
+               .result = "\xf5\x8c\x4c\x04\xd6\xe5\xf1\xba"
+                         "\x77\x9e\xab\xfb\x5f\x7b\xfb\xd6"
+                         "\x9c\xfc\x4e\x96\x7e\xdb\x80\x8d"
+                         "\x67\x9f\x77\x7b\xc6\x70\x2c\x7d"
+                         "\x39\xf2\x33\x69\xa9\xd9\xba\xcf"
+                         "\xa5\x30\xe2\x63\x04\x23\x14\x61"
+                         "\xb2\xeb\x05\xe2\xc3\x9b\xe9\xfc"
+                         "\xda\x6c\x19\x07\x8c\x6a\x9d\x1b",
+               .rlen   = 64,
+       },
+};
+
+static struct cipher_testvec aes_cbc_dec_tv_template[] = {
+       { /* From RFC 3602 */
+               .key    = "\x06\xa9\x21\x40\x36\xb8\xa1\x5b"
+                         "\x51\x2e\x03\xd5\x34\x12\x00\x06",
+               .klen   = 16,
+               .iv     = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30"
+                         "\xb4\x22\xda\x80\x2c\x9f\xac\x41",
+               .input  = "\xe3\x53\x77\x9c\x10\x79\xae\xb8"
+                         "\x27\x08\x94\x2d\xbe\x77\x18\x1a",
+               .ilen   = 16,
+               .result = "Single block msg",
+               .rlen   = 16,
+       }, {
+               .key    = "\xc2\x86\x69\x6d\x88\x7c\x9a\xa0"
+                         "\x61\x1b\xbb\x3e\x20\x25\xa4\x5a",
+               .klen   = 16,
+               .iv     = "\x56\x2e\x17\x99\x6d\x09\x3d\x28"
+                         "\xdd\xb3\xba\x69\x5a\x2e\x6f\x58",
+               .input  = "\xd2\x96\xcd\x94\xc2\xcc\xcf\x8a"
+                         "\x3a\x86\x30\x28\xb5\xe1\xdc\x0a"
+                         "\x75\x86\x60\x2d\x25\x3c\xff\xf9"
+                         "\x1b\x82\x66\xbe\xa6\xd6\x1a\xb1",
+               .ilen   = 32,
+               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .rlen   = 32,
+       }, { /* From NIST SP800-38A */
+               .key    = "\x8e\x73\xb0\xf7\xda\x0e\x64\x52"
+                         "\xc8\x10\xf3\x2b\x80\x90\x79\xe5"
+                         "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
+               .klen   = 24,
+               .iv     = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .input  = "\x4f\x02\x1d\xb2\x43\xbc\x63\x3d"
+                         "\x71\x78\x18\x3a\x9f\xa0\x71\xe8"
+                         "\xb4\xd9\xad\xa9\xad\x7d\xed\xf4"
+                         "\xe5\xe7\x38\x76\x3f\x69\x14\x5a"
+                         "\x57\x1b\x24\x20\x12\xfb\x7a\xe0"
+                         "\x7f\xa9\xba\xac\x3d\xf1\x02\xe0"
+                         "\x08\xb0\xe2\x79\x88\x59\x88\x81"
+                         "\xd9\x20\xa9\xe6\x4f\x56\x15\xcd",
+               .ilen   = 64,
+               .result = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+                         "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+                         "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+                         "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+                         "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+                         "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+                         "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+                         "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+               .rlen   = 64,
+       }, {
+               .key    = "\x60\x3d\xeb\x10\x15\xca\x71\xbe"
+                         "\x2b\x73\xae\xf0\x85\x7d\x77\x81"
+                         "\x1f\x35\x2c\x07\x3b\x61\x08\xd7"
+                         "\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
+               .klen   = 32,
+               .iv     = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .input  = "\xf5\x8c\x4c\x04\xd6\xe5\xf1\xba"
+                         "\x77\x9e\xab\xfb\x5f\x7b\xfb\xd6"
+                         "\x9c\xfc\x4e\x96\x7e\xdb\x80\x8d"
+                         "\x67\x9f\x77\x7b\xc6\x70\x2c\x7d"
+                         "\x39\xf2\x33\x69\xa9\xd9\xba\xcf"
+                         "\xa5\x30\xe2\x63\x04\x23\x14\x61"
+                         "\xb2\xeb\x05\xe2\xc3\x9b\xe9\xfc"
+                         "\xda\x6c\x19\x07\x8c\x6a\x9d\x1b",
+               .ilen   = 64,
+               .result = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+                         "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+                         "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+                         "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+                         "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+                         "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+                         "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+                         "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+               .rlen   = 64,
+       },
+};
+
+static struct cipher_testvec aes_lrw_enc_tv_template[] = {
+       /* from http://grouper.ieee.org/groups/1619/email/pdf00017.pdf */
+       { /* LRW-32-AES 1 */
+               .key    = "\x45\x62\xac\x25\xf8\x28\x17\x6d"
+                         "\x4c\x26\x84\x14\xb5\x68\x01\x85"
+                         "\x25\x8e\x2a\x05\xe7\x3e\x9d\x03"
+                         "\xee\x5a\x83\x0c\xcc\x09\x4c\x87",
+               .klen   = 32,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x01",
+               .input  = "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x41\x42\x43\x44\x45\x46",
+               .ilen   = 16,
+               .result = "\xf1\xb2\x73\xcd\x65\xa3\xdf\x5f"
+                         "\xe9\x5d\x48\x92\x54\x63\x4e\xb8",
+               .rlen   = 16,
+       }, { /* LRW-32-AES 2 */
+               .key    = "\x59\x70\x47\x14\xf5\x57\x47\x8c"
+                         "\xd7\x79\xe8\x0f\x54\x88\x79\x44"
+                         "\x0d\x48\xf0\xb7\xb1\x5a\x53\xea"
+                         "\x1c\xaa\x6b\x29\xc2\xca\xfb\xaf",
+               .klen   = 32,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x02",
+               .input  = "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x41\x42\x43\x44\x45\x46",
+               .ilen   = 16,
+               .result = "\x00\xc8\x2b\xae\x95\xbb\xcd\xe5"
+                         "\x27\x4f\x07\x69\xb2\x60\xe1\x36",
+               .rlen   = 16,
+       }, { /* LRW-32-AES 3 */
+               .key    = "\xd8\x2a\x91\x34\xb2\x6a\x56\x50"
+                         "\x30\xfe\x69\xe2\x37\x7f\x98\x47"
+                         "\xcd\xf9\x0b\x16\x0c\x64\x8f\xb6"
+                         "\xb0\x0d\x0d\x1b\xae\x85\x87\x1f",
+               .klen   = 32,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x02\x00\x00\x00\x00",
+               .input  = "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x41\x42\x43\x44\x45\x46",
+               .ilen   = 16,
+               .result = "\x76\x32\x21\x83\xed\x8f\xf1\x82"
+                         "\xf9\x59\x62\x03\x69\x0e\x5e\x01",
+               .rlen   = 16,
+       }, { /* LRW-32-AES 4 */
+               .key    = "\x0f\x6a\xef\xf8\xd3\xd2\xbb\x15"
+                         "\x25\x83\xf7\x3c\x1f\x01\x28\x74"
+                         "\xca\xc6\xbc\x35\x4d\x4a\x65\x54"
+                         "\x90\xae\x61\xcf\x7b\xae\xbd\xcc"
+                         "\xad\xe4\x94\xc5\x4a\x29\xae\x70",
+               .klen   = 40,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x01",
+               .input  = "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x41\x42\x43\x44\x45\x46",
+               .ilen   = 16,
+               .result = "\x9c\x0f\x15\x2f\x55\xa2\xd8\xf0"
+                         "\xd6\x7b\x8f\x9e\x28\x22\xbc\x41",
+               .rlen   = 16,
+       }, { /* LRW-32-AES 5 */
+               .key    = "\x8a\xd4\xee\x10\x2f\xbd\x81\xff"
+                         "\xf8\x86\xce\xac\x93\xc5\xad\xc6"
+                         "\xa0\x19\x07\xc0\x9d\xf7\xbb\xdd"
+                         "\x52\x13\xb2\xb7\xf0\xff\x11\xd8"
+                         "\xd6\x08\xd0\xcd\x2e\xb1\x17\x6f",
+               .klen   = 40,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x02\x00\x00\x00\x00",
+               .input  = "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x41\x42\x43\x44\x45\x46",
+               .ilen   = 16,
+               .result = "\xd4\x27\x6a\x7f\x14\x91\x3d\x65"
+                         "\xc8\x60\x48\x02\x87\xe3\x34\x06",
+               .rlen   = 16,
+       }, { /* LRW-32-AES 6 */
+               .key    = "\xf8\xd4\x76\xff\xd6\x46\xee\x6c"
+                         "\x23\x84\xcb\x1c\x77\xd6\x19\x5d"
+                         "\xfe\xf1\xa9\xf3\x7b\xbc\x8d\x21"
+                         "\xa7\x9c\x21\xf8\xcb\x90\x02\x89"
+                         "\xa8\x45\x34\x8e\xc8\xc5\xb5\xf1"
+                         "\x26\xf5\x0e\x76\xfe\xfd\x1b\x1e",
+               .klen   = 48,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x01",
+               .input  = "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x41\x42\x43\x44\x45\x46",
+               .ilen   = 16,
+               .result = "\xbd\x06\xb8\xe1\xdb\x98\x89\x9e"
+                         "\xc4\x98\xe4\x91\xcf\x1c\x70\x2b",
+               .rlen   = 16,
+       }, { /* LRW-32-AES 7 */
+               .key    = "\xfb\x76\x15\xb2\x3d\x80\x89\x1d"
+                         "\xd4\x70\x98\x0b\xc7\x95\x84\xc8"
+                         "\xb2\xfb\x64\xce\x60\x97\x87\x8d"
+                         "\x17\xfc\xe4\x5a\x49\xe8\x30\xb7"
+                         "\x6e\x78\x17\xe7\x2d\x5e\x12\xd4"
+                         "\x60\x64\x04\x7a\xf1\x2f\x9e\x0c",
+               .klen   = 48,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x02\x00\x00\x00\x00",
+               .input  = "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x41\x42\x43\x44\x45\x46",
+               .ilen   = 16,
+               .result = "\x5b\x90\x8e\xc1\xab\xdd\x67\x5f"
+                         "\x3d\x69\x8a\x95\x53\xc8\x9c\xe5",
+               .rlen   = 16,
+       }, {
+/* http://www.mail-archive.com/stds-p1619@listserv.ieee.org/msg00173.html */
+               .key    = "\xf8\xd4\x76\xff\xd6\x46\xee\x6c"
+                         "\x23\x84\xcb\x1c\x77\xd6\x19\x5d"
+                         "\xfe\xf1\xa9\xf3\x7b\xbc\x8d\x21"
+                         "\xa7\x9c\x21\xf8\xcb\x90\x02\x89"
+                         "\xa8\x45\x34\x8e\xc8\xc5\xb5\xf1"
+                         "\x26\xf5\x0e\x76\xfe\xfd\x1b\x1e",
+               .klen   = 48,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x01",
+               .input  = "\x05\x11\xb7\x18\xab\xc6\x2d\xac"
+                         "\x70\x5d\xf6\x22\x94\xcd\xe5\x6c"
+                         "\x17\x6b\xf6\x1c\xf0\xf3\x6e\xf8"
+                         "\x50\x38\x1f\x71\x49\xb6\x57\xd6"
+                         "\x8f\xcb\x8d\x6b\xe3\xa6\x29\x90"
+                         "\xfe\x2a\x62\x82\xae\x6d\x8b\xf6"
+                         "\xad\x1e\x9e\x20\x5f\x38\xbe\x04"
+                         "\xda\x10\x8e\xed\xa2\xa4\x87\xab"
+                         "\xda\x6b\xb4\x0c\x75\xba\xd3\x7c"
+                         "\xc9\xac\x42\x31\x95\x7c\xc9\x04"
+                         "\xeb\xd5\x6e\x32\x69\x8a\xdb\xa6"
+                         "\x15\xd7\x3f\x4f\x2f\x66\x69\x03"
+                         "\x9c\x1f\x54\x0f\xde\x1f\xf3\x65"
+                         "\x4c\x96\x12\xed\x7c\x92\x03\x01"
+                         "\x6f\xbc\x35\x93\xac\xf1\x27\xf1"
+                         "\xb4\x96\x82\x5a\x5f\xb0\xa0\x50"
+                         "\x89\xa4\x8e\x66\x44\x85\xcc\xfd"
+                         "\x33\x14\x70\xe3\x96\xb2\xc3\xd3"
+                         "\xbb\x54\x5a\x1a\xf9\x74\xa2\xc5"
+                         "\x2d\x64\x75\xdd\xb4\x54\xe6\x74"
+                         "\x8c\xd3\x9d\x9e\x86\xab\x51\x53"
+                         "\xb7\x93\x3e\x6f\xd0\x4e\x2c\x40"
+                         "\xf6\xa8\x2e\x3e\x9d\xf4\x66\xa5"
+                         "\x76\x12\x73\x44\x1a\x56\xd7\x72"
+                         "\x88\xcd\x21\x8c\x4c\x0f\xfe\xda"
+                         "\x95\xe0\x3a\xa6\xa5\x84\x46\xcd"
+                         "\xd5\x3e\x9d\x3a\xe2\x67\xe6\x60"
+                         "\x1a\xe2\x70\x85\x58\xc2\x1b\x09"
+                         "\xe1\xd7\x2c\xca\xad\xa8\x8f\xf9"
+                         "\xac\xb3\x0e\xdb\xca\x2e\xe2\xb8"
+                         "\x51\x71\xd9\x3c\x6c\xf1\x56\xf8"
+                         "\xea\x9c\xf1\xfb\x0c\xe6\xb7\x10"
+                         "\x1c\xf8\xa9\x7c\xe8\x53\x35\xc1"
+                         "\x90\x3e\x76\x4a\x74\xa4\x21\x2c"
+                         "\xf6\x2c\x4e\x0f\x94\x3a\x88\x2e"
+                         "\x41\x09\x6a\x33\x7d\xf6\xdd\x3f"
+                         "\x8d\x23\x31\x74\x84\xeb\x88\x6e"
+                         "\xcc\xb9\xbc\x22\x83\x19\x07\x22"
+                         "\xa5\x2d\xdf\xa5\xf3\x80\x85\x78"
+                         "\x84\x39\x6a\x6d\x6a\x99\x4f\xa5"
+                         "\x15\xfe\x46\xb0\xe4\x6c\xa5\x41"
+                         "\x3c\xce\x8f\x42\x60\x71\xa7\x75"
+                         "\x08\x40\x65\x8a\x82\xbf\xf5\x43"
+                         "\x71\x96\xa9\x4d\x44\x8a\x20\xbe"
+                         "\xfa\x4d\xbb\xc0\x7d\x31\x96\x65"
+                         "\xe7\x75\xe5\x3e\xfd\x92\x3b\xc9"
+                         "\x55\xbb\x16\x7e\xf7\xc2\x8c\xa4"
+                         "\x40\x1d\xe5\xef\x0e\xdf\xe4\x9a"
+                         "\x62\x73\x65\xfd\x46\x63\x25\x3d"
+                         "\x2b\xaf\xe5\x64\xfe\xa5\x5c\xcf"
+                         "\x24\xf3\xb4\xac\x64\xba\xdf\x4b"
+                         "\xc6\x96\x7d\x81\x2d\x8d\x97\xf7"
+                         "\xc5\x68\x77\x84\x32\x2b\xcc\x85"
+                         "\x74\x96\xf0\x12\x77\x61\xb9\xeb"
+                         "\x71\xaa\x82\xcb\x1c\xdb\x89\xc8"
+                         "\xc6\xb5\xe3\x5c\x7d\x39\x07\x24"
+                         "\xda\x39\x87\x45\xc0\x2b\xbb\x01"
+                         "\xac\xbc\x2a\x5c\x7f\xfc\xe8\xce"
+                         "\x6d\x9c\x6f\xed\xd3\xc1\xa1\xd6"
+                         "\xc5\x55\xa9\x66\x2f\xe1\xc8\x32"
+                         "\xa6\x5d\xa4\x3a\x98\x73\xe8\x45"
+                         "\xa4\xc7\xa8\xb4\xf6\x13\x03\xf6"
+                         "\xe9\x2e\xc4\x29\x0f\x84\xdb\xc4"
+                         "\x21\xc4\xc2\x75\x67\x89\x37\x0a",
+               .ilen   = 512,
+               .result = "\x1a\x1d\xa9\x30\xad\xf9\x2f\x9b"
+                         "\xb6\x1d\xae\xef\xf0\x2f\xf8\x5a"
+                         "\x39\x3c\xbf\x2a\xb2\x45\xb2\x23"
+                         "\x1b\x63\x3c\xcf\xaa\xbe\xcf\x4e"
+                         "\xfa\xe8\x29\xc2\x20\x68\x2b\x3c"
+                         "\x2e\x8b\xf7\x6e\x25\xbd\xe3\x3d"
+                         "\x66\x27\xd6\xaf\xd6\x64\x3e\xe3"
+                         "\xe8\x58\x46\x97\x39\x51\x07\xde"
+                         "\xcb\x37\xbc\xa9\xc0\x5f\x75\xc3"
+                         "\x0e\x84\x23\x1d\x16\xd4\x1c\x59"
+                         "\x9c\x1a\x02\x55\xab\x3a\x97\x1d"
+                         "\xdf\xdd\xc7\x06\x51\xd7\x70\xae"
+                         "\x23\xc6\x8c\xf5\x1e\xa0\xe5\x82"
+                         "\xb8\xb2\xbf\x04\xa0\x32\x8e\x68"
+                         "\xeb\xaf\x6e\x2d\x94\x22\x2f\xce"
+                         "\x4c\xb5\x59\xe2\xa2\x2f\xa0\x98"
+                         "\x1a\x97\xc6\xd4\xb5\x00\x59\xf2"
+                         "\x84\x14\x72\xb1\x9a\x6e\xa3\x7f"
+                         "\xea\x20\xe7\xcb\x65\x77\x3a\xdf"
+                         "\xc8\x97\x67\x15\xc2\x2a\x27\xcc"
+                         "\x18\x55\xa1\x24\x0b\x24\x24\xaf"
+                         "\x5b\xec\x68\xb8\xc8\xf5\xba\x63"
+                         "\xff\xed\x89\xce\xd5\x3d\x88\xf3"
+                         "\x25\xef\x05\x7c\x3a\xef\xeb\xd8"
+                         "\x7a\x32\x0d\xd1\x1e\x58\x59\x99"
+                         "\x90\x25\xb5\x26\xb0\xe3\x2b\x6c"
+                         "\x4c\xa9\x8b\x84\x4f\x5e\x01\x50"
+                         "\x41\x30\x58\xc5\x62\x74\x52\x1d"
+                         "\x45\x24\x6a\x42\x64\x4f\x97\x1c"
+                         "\xa8\x66\xb5\x6d\x79\xd4\x0d\x48"
+                         "\xc5\x5f\xf3\x90\x32\xdd\xdd\xe1"
+                         "\xe4\xa9\x9f\xfc\xc3\x52\x5a\x46"
+                         "\xe4\x81\x84\x95\x36\x59\x7a\x6b"
+                         "\xaa\xb3\x60\xad\xce\x9f\x9f\x28"
+                         "\xe0\x01\x75\x22\xc4\x4e\xa9\x62"
+                         "\x5c\x62\x0d\x00\xcb\x13\xe8\x43"
+                         "\x72\xd4\x2d\x53\x46\xb5\xd1\x16"
+                         "\x22\x18\xdf\x34\x33\xf5\xd6\x1c"
+                         "\xb8\x79\x78\x97\x94\xff\x72\x13"
+                         "\x4c\x27\xfc\xcb\xbf\x01\x53\xa6"
+                         "\xb4\x50\x6e\xde\xdf\xb5\x43\xa4"
+                         "\x59\xdf\x52\xf9\x7c\xe0\x11\x6f"
+                         "\x2d\x14\x8e\x24\x61\x2c\xe1\x17"
+                         "\xcc\xce\x51\x0c\x19\x8a\x82\x30"
+                         "\x94\xd5\x3d\x6a\x53\x06\x5e\xbd"
+                         "\xb7\xeb\xfa\xfd\x27\x51\xde\x85"
+                         "\x1e\x86\x53\x11\x53\x94\x00\xee"
+                         "\x2b\x8c\x08\x2a\xbf\xdd\xae\x11"
+                         "\xcb\x1e\xa2\x07\x9a\x80\xcf\x62"
+                         "\x9b\x09\xdc\x95\x3c\x96\x8e\xb1"
+                         "\x09\xbd\xe4\xeb\xdb\xca\x70\x7a"
+                         "\x9e\xfa\x31\x18\x45\x3c\x21\x33"
+                         "\xb0\xb3\x2b\xea\xf3\x71\x2d\xe1"
+                         "\x03\xad\x1b\x48\xd4\x67\x27\xf0"
+                         "\x62\xe4\x3d\xfb\x9b\x08\x76\xe7"
+                         "\xdd\x2b\x01\x39\x04\x5a\x58\x7a"
+                         "\xf7\x11\x90\xec\xbd\x51\x5c\x32"
+                         "\x6b\xd7\x35\x39\x02\x6b\xf2\xa6"
+                         "\xd0\x0d\x07\xe1\x06\xc4\x5b\x7d"
+                         "\xe4\x6a\xd7\xee\x15\x1f\x83\xb4"
+                         "\xa3\xa7\x5e\xc3\x90\xb7\xef\xd3"
+                         "\xb7\x4f\xf8\x92\x4c\xb7\x3c\x29"
+                         "\xcd\x7e\x2b\x5d\x43\xea\x42\xe7"
+                         "\x74\x3f\x7d\x58\x88\x75\xde\x3e",
+               .rlen   = 512,
+       }
+};
+
+static struct cipher_testvec aes_lrw_dec_tv_template[] = {
+       /* from http://grouper.ieee.org/groups/1619/email/pdf00017.pdf */
+       /* same as enc vectors with input and result reversed */
+       { /* LRW-32-AES 1 */
+               .key    = "\x45\x62\xac\x25\xf8\x28\x17\x6d"
+                         "\x4c\x26\x84\x14\xb5\x68\x01\x85"
+                         "\x25\x8e\x2a\x05\xe7\x3e\x9d\x03"
+                         "\xee\x5a\x83\x0c\xcc\x09\x4c\x87",
+               .klen   = 32,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x01",
+               .input  = "\xf1\xb2\x73\xcd\x65\xa3\xdf\x5f"
+                         "\xe9\x5d\x48\x92\x54\x63\x4e\xb8",
+               .ilen   = 16,
+               .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x41\x42\x43\x44\x45\x46",
+               .rlen   = 16,
+       }, { /* LRW-32-AES 2 */
+               .key    = "\x59\x70\x47\x14\xf5\x57\x47\x8c"
+                         "\xd7\x79\xe8\x0f\x54\x88\x79\x44"
+                         "\x0d\x48\xf0\xb7\xb1\x5a\x53\xea"
+                         "\x1c\xaa\x6b\x29\xc2\xca\xfb\xaf",
+               .klen   = 32,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x02",
+               .input  = "\x00\xc8\x2b\xae\x95\xbb\xcd\xe5"
+                         "\x27\x4f\x07\x69\xb2\x60\xe1\x36",
+               .ilen   = 16,
+               .result  = "\x30\x31\x32\x33\x34\x35\x36\x37"
+                          "\x38\x39\x41\x42\x43\x44\x45\x46",
+               .rlen   = 16,
+       }, { /* LRW-32-AES 3 */
+               .key    = "\xd8\x2a\x91\x34\xb2\x6a\x56\x50"
+                         "\x30\xfe\x69\xe2\x37\x7f\x98\x47"
+                         "\xcd\xf9\x0b\x16\x0c\x64\x8f\xb6"
+                         "\xb0\x0d\x0d\x1b\xae\x85\x87\x1f",
+               .klen   = 32,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x02\x00\x00\x00\x00",
+               .input  = "\x76\x32\x21\x83\xed\x8f\xf1\x82"
+                         "\xf9\x59\x62\x03\x69\x0e\x5e\x01",
+               .ilen   = 16,
+               .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x41\x42\x43\x44\x45\x46",
+               .rlen   = 16,
+       }, { /* LRW-32-AES 4 */
+               .key    = "\x0f\x6a\xef\xf8\xd3\xd2\xbb\x15"
+                         "\x25\x83\xf7\x3c\x1f\x01\x28\x74"
+                         "\xca\xc6\xbc\x35\x4d\x4a\x65\x54"
+                         "\x90\xae\x61\xcf\x7b\xae\xbd\xcc"
+                         "\xad\xe4\x94\xc5\x4a\x29\xae\x70",
+               .klen   = 40,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x01",
+               .input  = "\x9c\x0f\x15\x2f\x55\xa2\xd8\xf0"
+                         "\xd6\x7b\x8f\x9e\x28\x22\xbc\x41",
+               .ilen   = 16,
+               .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x41\x42\x43\x44\x45\x46",
+               .rlen   = 16,
+       }, { /* LRW-32-AES 5 */
+               .key    = "\x8a\xd4\xee\x10\x2f\xbd\x81\xff"
+                         "\xf8\x86\xce\xac\x93\xc5\xad\xc6"
+                         "\xa0\x19\x07\xc0\x9d\xf7\xbb\xdd"
+                         "\x52\x13\xb2\xb7\xf0\xff\x11\xd8"
+                         "\xd6\x08\xd0\xcd\x2e\xb1\x17\x6f",
+               .klen   = 40,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x02\x00\x00\x00\x00",
+               .input  = "\xd4\x27\x6a\x7f\x14\x91\x3d\x65"
+                         "\xc8\x60\x48\x02\x87\xe3\x34\x06",
+               .ilen   = 16,
+               .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x41\x42\x43\x44\x45\x46",
+               .rlen   = 16,
+       }, { /* LRW-32-AES 6 */
+               .key    = "\xf8\xd4\x76\xff\xd6\x46\xee\x6c"
+                         "\x23\x84\xcb\x1c\x77\xd6\x19\x5d"
+                         "\xfe\xf1\xa9\xf3\x7b\xbc\x8d\x21"
+                         "\xa7\x9c\x21\xf8\xcb\x90\x02\x89"
+                         "\xa8\x45\x34\x8e\xc8\xc5\xb5\xf1"
+                         "\x26\xf5\x0e\x76\xfe\xfd\x1b\x1e",
+               .klen   = 48,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x01",
+               .input  = "\xbd\x06\xb8\xe1\xdb\x98\x89\x9e"
+                         "\xc4\x98\xe4\x91\xcf\x1c\x70\x2b",
+               .ilen   = 16,
+               .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x41\x42\x43\x44\x45\x46",
+               .rlen   = 16,
+       }, { /* LRW-32-AES 7 */
+               .key    = "\xfb\x76\x15\xb2\x3d\x80\x89\x1d"
+                         "\xd4\x70\x98\x0b\xc7\x95\x84\xc8"
+                         "\xb2\xfb\x64\xce\x60\x97\x87\x8d"
+                         "\x17\xfc\xe4\x5a\x49\xe8\x30\xb7"
+                         "\x6e\x78\x17\xe7\x2d\x5e\x12\xd4"
+                         "\x60\x64\x04\x7a\xf1\x2f\x9e\x0c",
+               .klen   = 48,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x02\x00\x00\x00\x00",
+               .input  = "\x5b\x90\x8e\xc1\xab\xdd\x67\x5f"
+                         "\x3d\x69\x8a\x95\x53\xc8\x9c\xe5",
+               .ilen   = 16,
+               .result = "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x41\x42\x43\x44\x45\x46",
+               .rlen   = 16,
+       }, {
+/* http://www.mail-archive.com/stds-p1619@listserv.ieee.org/msg00173.html */
+               .key    = "\xf8\xd4\x76\xff\xd6\x46\xee\x6c"
+                         "\x23\x84\xcb\x1c\x77\xd6\x19\x5d"
+                         "\xfe\xf1\xa9\xf3\x7b\xbc\x8d\x21"
+                         "\xa7\x9c\x21\xf8\xcb\x90\x02\x89"
+                         "\xa8\x45\x34\x8e\xc8\xc5\xb5\xf1"
+                         "\x26\xf5\x0e\x76\xfe\xfd\x1b\x1e",
+               .klen   = 48,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x01",
+               .input  = "\x1a\x1d\xa9\x30\xad\xf9\x2f\x9b"
+                         "\xb6\x1d\xae\xef\xf0\x2f\xf8\x5a"
+                         "\x39\x3c\xbf\x2a\xb2\x45\xb2\x23"
+                         "\x1b\x63\x3c\xcf\xaa\xbe\xcf\x4e"
+                         "\xfa\xe8\x29\xc2\x20\x68\x2b\x3c"
+                         "\x2e\x8b\xf7\x6e\x25\xbd\xe3\x3d"
+                         "\x66\x27\xd6\xaf\xd6\x64\x3e\xe3"
+                         "\xe8\x58\x46\x97\x39\x51\x07\xde"
+                         "\xcb\x37\xbc\xa9\xc0\x5f\x75\xc3"
+                         "\x0e\x84\x23\x1d\x16\xd4\x1c\x59"
+                         "\x9c\x1a\x02\x55\xab\x3a\x97\x1d"
+                         "\xdf\xdd\xc7\x06\x51\xd7\x70\xae"
+                         "\x23\xc6\x8c\xf5\x1e\xa0\xe5\x82"
+                         "\xb8\xb2\xbf\x04\xa0\x32\x8e\x68"
+                         "\xeb\xaf\x6e\x2d\x94\x22\x2f\xce"
+                         "\x4c\xb5\x59\xe2\xa2\x2f\xa0\x98"
+                         "\x1a\x97\xc6\xd4\xb5\x00\x59\xf2"
+                         "\x84\x14\x72\xb1\x9a\x6e\xa3\x7f"
+                         "\xea\x20\xe7\xcb\x65\x77\x3a\xdf"
+                         "\xc8\x97\x67\x15\xc2\x2a\x27\xcc"
+                         "\x18\x55\xa1\x24\x0b\x24\x24\xaf"
+                         "\x5b\xec\x68\xb8\xc8\xf5\xba\x63"
+                         "\xff\xed\x89\xce\xd5\x3d\x88\xf3"
+                         "\x25\xef\x05\x7c\x3a\xef\xeb\xd8"
+                         "\x7a\x32\x0d\xd1\x1e\x58\x59\x99"
+                         "\x90\x25\xb5\x26\xb0\xe3\x2b\x6c"
+                         "\x4c\xa9\x8b\x84\x4f\x5e\x01\x50"
+                         "\x41\x30\x58\xc5\x62\x74\x52\x1d"
+                         "\x45\x24\x6a\x42\x64\x4f\x97\x1c"
+                         "\xa8\x66\xb5\x6d\x79\xd4\x0d\x48"
+                         "\xc5\x5f\xf3\x90\x32\xdd\xdd\xe1"
+                         "\xe4\xa9\x9f\xfc\xc3\x52\x5a\x46"
+                         "\xe4\x81\x84\x95\x36\x59\x7a\x6b"
+                         "\xaa\xb3\x60\xad\xce\x9f\x9f\x28"
+                         "\xe0\x01\x75\x22\xc4\x4e\xa9\x62"
+                         "\x5c\x62\x0d\x00\xcb\x13\xe8\x43"
+                         "\x72\xd4\x2d\x53\x46\xb5\xd1\x16"
+                         "\x22\x18\xdf\x34\x33\xf5\xd6\x1c"
+                         "\xb8\x79\x78\x97\x94\xff\x72\x13"
+                         "\x4c\x27\xfc\xcb\xbf\x01\x53\xa6"
+                         "\xb4\x50\x6e\xde\xdf\xb5\x43\xa4"
+                         "\x59\xdf\x52\xf9\x7c\xe0\x11\x6f"
+                         "\x2d\x14\x8e\x24\x61\x2c\xe1\x17"
+                         "\xcc\xce\x51\x0c\x19\x8a\x82\x30"
+                         "\x94\xd5\x3d\x6a\x53\x06\x5e\xbd"
+                         "\xb7\xeb\xfa\xfd\x27\x51\xde\x85"
+                         "\x1e\x86\x53\x11\x53\x94\x00\xee"
+                         "\x2b\x8c\x08\x2a\xbf\xdd\xae\x11"
+                         "\xcb\x1e\xa2\x07\x9a\x80\xcf\x62"
+                         "\x9b\x09\xdc\x95\x3c\x96\x8e\xb1"
+                         "\x09\xbd\xe4\xeb\xdb\xca\x70\x7a"
+                         "\x9e\xfa\x31\x18\x45\x3c\x21\x33"
+                         "\xb0\xb3\x2b\xea\xf3\x71\x2d\xe1"
+                         "\x03\xad\x1b\x48\xd4\x67\x27\xf0"
+                         "\x62\xe4\x3d\xfb\x9b\x08\x76\xe7"
+                         "\xdd\x2b\x01\x39\x04\x5a\x58\x7a"
+                         "\xf7\x11\x90\xec\xbd\x51\x5c\x32"
+                         "\x6b\xd7\x35\x39\x02\x6b\xf2\xa6"
+                         "\xd0\x0d\x07\xe1\x06\xc4\x5b\x7d"
+                         "\xe4\x6a\xd7\xee\x15\x1f\x83\xb4"
+                         "\xa3\xa7\x5e\xc3\x90\xb7\xef\xd3"
+                         "\xb7\x4f\xf8\x92\x4c\xb7\x3c\x29"
+                         "\xcd\x7e\x2b\x5d\x43\xea\x42\xe7"
+                         "\x74\x3f\x7d\x58\x88\x75\xde\x3e",
+               .ilen   = 512,
+               .result = "\x05\x11\xb7\x18\xab\xc6\x2d\xac"
+                         "\x70\x5d\xf6\x22\x94\xcd\xe5\x6c"
+                         "\x17\x6b\xf6\x1c\xf0\xf3\x6e\xf8"
+                         "\x50\x38\x1f\x71\x49\xb6\x57\xd6"
+                         "\x8f\xcb\x8d\x6b\xe3\xa6\x29\x90"
+                         "\xfe\x2a\x62\x82\xae\x6d\x8b\xf6"
+                         "\xad\x1e\x9e\x20\x5f\x38\xbe\x04"
+                         "\xda\x10\x8e\xed\xa2\xa4\x87\xab"
+                         "\xda\x6b\xb4\x0c\x75\xba\xd3\x7c"
+                         "\xc9\xac\x42\x31\x95\x7c\xc9\x04"
+                         "\xeb\xd5\x6e\x32\x69\x8a\xdb\xa6"
+                         "\x15\xd7\x3f\x4f\x2f\x66\x69\x03"
+                         "\x9c\x1f\x54\x0f\xde\x1f\xf3\x65"
+                         "\x4c\x96\x12\xed\x7c\x92\x03\x01"
+                         "\x6f\xbc\x35\x93\xac\xf1\x27\xf1"
+                         "\xb4\x96\x82\x5a\x5f\xb0\xa0\x50"
+                         "\x89\xa4\x8e\x66\x44\x85\xcc\xfd"
+                         "\x33\x14\x70\xe3\x96\xb2\xc3\xd3"
+                         "\xbb\x54\x5a\x1a\xf9\x74\xa2\xc5"
+                         "\x2d\x64\x75\xdd\xb4\x54\xe6\x74"
+                         "\x8c\xd3\x9d\x9e\x86\xab\x51\x53"
+                         "\xb7\x93\x3e\x6f\xd0\x4e\x2c\x40"
+                         "\xf6\xa8\x2e\x3e\x9d\xf4\x66\xa5"
+                         "\x76\x12\x73\x44\x1a\x56\xd7\x72"
+                         "\x88\xcd\x21\x8c\x4c\x0f\xfe\xda"
+                         "\x95\xe0\x3a\xa6\xa5\x84\x46\xcd"
+                         "\xd5\x3e\x9d\x3a\xe2\x67\xe6\x60"
+                         "\x1a\xe2\x70\x85\x58\xc2\x1b\x09"
+                         "\xe1\xd7\x2c\xca\xad\xa8\x8f\xf9"
+                         "\xac\xb3\x0e\xdb\xca\x2e\xe2\xb8"
+                         "\x51\x71\xd9\x3c\x6c\xf1\x56\xf8"
+                         "\xea\x9c\xf1\xfb\x0c\xe6\xb7\x10"
+                         "\x1c\xf8\xa9\x7c\xe8\x53\x35\xc1"
+                         "\x90\x3e\x76\x4a\x74\xa4\x21\x2c"
+                         "\xf6\x2c\x4e\x0f\x94\x3a\x88\x2e"
+                         "\x41\x09\x6a\x33\x7d\xf6\xdd\x3f"
+                         "\x8d\x23\x31\x74\x84\xeb\x88\x6e"
+                         "\xcc\xb9\xbc\x22\x83\x19\x07\x22"
+                         "\xa5\x2d\xdf\xa5\xf3\x80\x85\x78"
+                         "\x84\x39\x6a\x6d\x6a\x99\x4f\xa5"
+                         "\x15\xfe\x46\xb0\xe4\x6c\xa5\x41"
+                         "\x3c\xce\x8f\x42\x60\x71\xa7\x75"
+                         "\x08\x40\x65\x8a\x82\xbf\xf5\x43"
+                         "\x71\x96\xa9\x4d\x44\x8a\x20\xbe"
+                         "\xfa\x4d\xbb\xc0\x7d\x31\x96\x65"
+                         "\xe7\x75\xe5\x3e\xfd\x92\x3b\xc9"
+                         "\x55\xbb\x16\x7e\xf7\xc2\x8c\xa4"
+                         "\x40\x1d\xe5\xef\x0e\xdf\xe4\x9a"
+                         "\x62\x73\x65\xfd\x46\x63\x25\x3d"
+                         "\x2b\xaf\xe5\x64\xfe\xa5\x5c\xcf"
+                         "\x24\xf3\xb4\xac\x64\xba\xdf\x4b"
+                         "\xc6\x96\x7d\x81\x2d\x8d\x97\xf7"
+                         "\xc5\x68\x77\x84\x32\x2b\xcc\x85"
+                         "\x74\x96\xf0\x12\x77\x61\xb9\xeb"
+                         "\x71\xaa\x82\xcb\x1c\xdb\x89\xc8"
+                         "\xc6\xb5\xe3\x5c\x7d\x39\x07\x24"
+                         "\xda\x39\x87\x45\xc0\x2b\xbb\x01"
+                         "\xac\xbc\x2a\x5c\x7f\xfc\xe8\xce"
+                         "\x6d\x9c\x6f\xed\xd3\xc1\xa1\xd6"
+                         "\xc5\x55\xa9\x66\x2f\xe1\xc8\x32"
+                         "\xa6\x5d\xa4\x3a\x98\x73\xe8\x45"
+                         "\xa4\xc7\xa8\xb4\xf6\x13\x03\xf6"
+                         "\xe9\x2e\xc4\x29\x0f\x84\xdb\xc4"
+                         "\x21\xc4\xc2\x75\x67\x89\x37\x0a",
+               .rlen   = 512,
+       }
+};
+
+static struct cipher_testvec aes_xts_enc_tv_template[] = {
+       /* http://grouper.ieee.org/groups/1619/email/pdf00086.pdf */
+       { /* XTS-AES 1 */
+               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 32,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .ilen   = 32,
+               .result = "\x91\x7c\xf6\x9e\xbd\x68\xb2\xec"
+                         "\x9b\x9f\xe9\xa3\xea\xdd\xa6\x92"
+                         "\xcd\x43\xd2\xf5\x95\x98\xed\x85"
+                         "\x8c\x02\xc2\x65\x2f\xbf\x92\x2e",
+               .rlen   = 32,
+       }, { /* XTS-AES 2 */
+               .key    = "\x11\x11\x11\x11\x11\x11\x11\x11"
+                         "\x11\x11\x11\x11\x11\x11\x11\x11"
+                         "\x22\x22\x22\x22\x22\x22\x22\x22"
+                         "\x22\x22\x22\x22\x22\x22\x22\x22",
+               .klen   = 32,
+               .iv     = "\x33\x33\x33\x33\x33\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "\x44\x44\x44\x44\x44\x44\x44\x44"
+                         "\x44\x44\x44\x44\x44\x44\x44\x44"
+                         "\x44\x44\x44\x44\x44\x44\x44\x44"
+                         "\x44\x44\x44\x44\x44\x44\x44\x44",
+               .ilen   = 32,
+               .result = "\xc4\x54\x18\x5e\x6a\x16\x93\x6e"
+                         "\x39\x33\x40\x38\xac\xef\x83\x8b"
+                         "\xfb\x18\x6f\xff\x74\x80\xad\xc4"
+                         "\x28\x93\x82\xec\xd6\xd3\x94\xf0",
+               .rlen   = 32,
+       }, { /* XTS-AES 3 */
+               .key    = "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8"
+                         "\xf7\xf6\xf5\xf4\xf3\xf2\xf1\xf0"
+                         "\x22\x22\x22\x22\x22\x22\x22\x22"
+                         "\x22\x22\x22\x22\x22\x22\x22\x22",
+               .klen   = 32,
+               .iv     = "\x33\x33\x33\x33\x33\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "\x44\x44\x44\x44\x44\x44\x44\x44"
+                         "\x44\x44\x44\x44\x44\x44\x44\x44"
+                         "\x44\x44\x44\x44\x44\x44\x44\x44"
+                         "\x44\x44\x44\x44\x44\x44\x44\x44",
+               .ilen   = 32,
+               .result = "\xaf\x85\x33\x6b\x59\x7a\xfc\x1a"
+                         "\x90\x0b\x2e\xb2\x1e\xc9\x49\xd2"
+                         "\x92\xdf\x4c\x04\x7e\x0b\x21\x53"
+                         "\x21\x86\xa5\x97\x1a\x22\x7a\x89",
+               .rlen   = 32,
+       }, { /* XTS-AES 4 */
+               .key    = "\x27\x18\x28\x18\x28\x45\x90\x45"
+                         "\x23\x53\x60\x28\x74\x71\x35\x26"
+                         "\x31\x41\x59\x26\x53\x58\x97\x93"
+                         "\x23\x84\x62\x64\x33\x83\x27\x95",
+               .klen   = 32,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+                         "\x20\x21\x22\x23\x24\x25\x26\x27"
+                         "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+                         "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+                         "\x40\x41\x42\x43\x44\x45\x46\x47"
+                         "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+                         "\x50\x51\x52\x53\x54\x55\x56\x57"
+                         "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+                         "\x60\x61\x62\x63\x64\x65\x66\x67"
+                         "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+                         "\x70\x71\x72\x73\x74\x75\x76\x77"
+                         "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+                         "\x80\x81\x82\x83\x84\x85\x86\x87"
+                         "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+                         "\x90\x91\x92\x93\x94\x95\x96\x97"
+                         "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+                         "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+                         "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+                         "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+                         "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+                         "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+                         "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+                         "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+                         "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+                         "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+                         "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+                         "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
+                         "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+                         "\x20\x21\x22\x23\x24\x25\x26\x27"
+                         "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+                         "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+                         "\x40\x41\x42\x43\x44\x45\x46\x47"
+                         "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+                         "\x50\x51\x52\x53\x54\x55\x56\x57"
+                         "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+                         "\x60\x61\x62\x63\x64\x65\x66\x67"
+                         "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+                         "\x70\x71\x72\x73\x74\x75\x76\x77"
+                         "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+                         "\x80\x81\x82\x83\x84\x85\x86\x87"
+                         "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+                         "\x90\x91\x92\x93\x94\x95\x96\x97"
+                         "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+                         "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+                         "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+                         "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+                         "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+                         "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+                         "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+                         "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+                         "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+                         "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+                         "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+                         "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+               .ilen   = 512,
+               .result = "\x27\xa7\x47\x9b\xef\xa1\xd4\x76"
+                         "\x48\x9f\x30\x8c\xd4\xcf\xa6\xe2"
+                         "\xa9\x6e\x4b\xbe\x32\x08\xff\x25"
+                         "\x28\x7d\xd3\x81\x96\x16\xe8\x9c"
+                         "\xc7\x8c\xf7\xf5\xe5\x43\x44\x5f"
+                         "\x83\x33\xd8\xfa\x7f\x56\x00\x00"
+                         "\x05\x27\x9f\xa5\xd8\xb5\xe4\xad"
+                         "\x40\xe7\x36\xdd\xb4\xd3\x54\x12"
+                         "\x32\x80\x63\xfd\x2a\xab\x53\xe5"
+                         "\xea\x1e\x0a\x9f\x33\x25\x00\xa5"
+                         "\xdf\x94\x87\xd0\x7a\x5c\x92\xcc"
+                         "\x51\x2c\x88\x66\xc7\xe8\x60\xce"
+                         "\x93\xfd\xf1\x66\xa2\x49\x12\xb4"
+                         "\x22\x97\x61\x46\xae\x20\xce\x84"
+                         "\x6b\xb7\xdc\x9b\xa9\x4a\x76\x7a"
+                         "\xae\xf2\x0c\x0d\x61\xad\x02\x65"
+                         "\x5e\xa9\x2d\xc4\xc4\xe4\x1a\x89"
+                         "\x52\xc6\x51\xd3\x31\x74\xbe\x51"
+                         "\xa1\x0c\x42\x11\x10\xe6\xd8\x15"
+                         "\x88\xed\xe8\x21\x03\xa2\x52\xd8"
+                         "\xa7\x50\xe8\x76\x8d\xef\xff\xed"
+                         "\x91\x22\x81\x0a\xae\xb9\x9f\x91"
+                         "\x72\xaf\x82\xb6\x04\xdc\x4b\x8e"
+                         "\x51\xbc\xb0\x82\x35\xa6\xf4\x34"
+                         "\x13\x32\xe4\xca\x60\x48\x2a\x4b"
+                         "\xa1\xa0\x3b\x3e\x65\x00\x8f\xc5"
+                         "\xda\x76\xb7\x0b\xf1\x69\x0d\xb4"
+                         "\xea\xe2\x9c\x5f\x1b\xad\xd0\x3c"
+                         "\x5c\xcf\x2a\x55\xd7\x05\xdd\xcd"
+                         "\x86\xd4\x49\x51\x1c\xeb\x7e\xc3"
+                         "\x0b\xf1\x2b\x1f\xa3\x5b\x91\x3f"
+                         "\x9f\x74\x7a\x8a\xfd\x1b\x13\x0e"
+                         "\x94\xbf\xf9\x4e\xff\xd0\x1a\x91"
+                         "\x73\x5c\xa1\x72\x6a\xcd\x0b\x19"
+                         "\x7c\x4e\x5b\x03\x39\x36\x97\xe1"
+                         "\x26\x82\x6f\xb6\xbb\xde\x8e\xcc"
+                         "\x1e\x08\x29\x85\x16\xe2\xc9\xed"
+                         "\x03\xff\x3c\x1b\x78\x60\xf6\xde"
+                         "\x76\xd4\xce\xcd\x94\xc8\x11\x98"
+                         "\x55\xef\x52\x97\xca\x67\xe9\xf3"
+                         "\xe7\xff\x72\xb1\xe9\x97\x85\xca"
+                         "\x0a\x7e\x77\x20\xc5\xb3\x6d\xc6"
+                         "\xd7\x2c\xac\x95\x74\xc8\xcb\xbc"
+                         "\x2f\x80\x1e\x23\xe5\x6f\xd3\x44"
+                         "\xb0\x7f\x22\x15\x4b\xeb\xa0\xf0"
+                         "\x8c\xe8\x89\x1e\x64\x3e\xd9\x95"
+                         "\xc9\x4d\x9a\x69\xc9\xf1\xb5\xf4"
+                         "\x99\x02\x7a\x78\x57\x2a\xee\xbd"
+                         "\x74\xd2\x0c\xc3\x98\x81\xc2\x13"
+                         "\xee\x77\x0b\x10\x10\xe4\xbe\xa7"
+                         "\x18\x84\x69\x77\xae\x11\x9f\x7a"
+                         "\x02\x3a\xb5\x8c\xca\x0a\xd7\x52"
+                         "\xaf\xe6\x56\xbb\x3c\x17\x25\x6a"
+                         "\x9f\x6e\x9b\xf1\x9f\xdd\x5a\x38"
+                         "\xfc\x82\xbb\xe8\x72\xc5\x53\x9e"
+                         "\xdb\x60\x9e\xf4\xf7\x9c\x20\x3e"
+                         "\xbb\x14\x0f\x2e\x58\x3c\xb2\xad"
+                         "\x15\xb4\xaa\x5b\x65\x50\x16\xa8"
+                         "\x44\x92\x77\xdb\xd4\x77\xef\x2c"
+                         "\x8d\x6c\x01\x7d\xb7\x38\xb1\x8d"
+                         "\xeb\x4a\x42\x7d\x19\x23\xce\x3f"
+                         "\xf2\x62\x73\x57\x79\xa4\x18\xf2"
+                         "\x0a\x28\x2d\xf9\x20\x14\x7b\xea"
+                         "\xbe\x42\x1e\xe5\x31\x9d\x05\x68",
+               .rlen   = 512,
+       }
+};
+
+static struct cipher_testvec aes_xts_dec_tv_template[] = {
+       /* http://grouper.ieee.org/groups/1619/email/pdf00086.pdf */
+       { /* XTS-AES 1 */
+               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 32,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input = "\x91\x7c\xf6\x9e\xbd\x68\xb2\xec"
+                        "\x9b\x9f\xe9\xa3\xea\xdd\xa6\x92"
+                        "\xcd\x43\xd2\xf5\x95\x98\xed\x85"
+                        "\x8c\x02\xc2\x65\x2f\xbf\x92\x2e",
+               .ilen   = 32,
+               .result  = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                          "\x00\x00\x00\x00\x00\x00\x00\x00"
+                          "\x00\x00\x00\x00\x00\x00\x00\x00"
+                          "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .rlen   = 32,
+       }, { /* XTS-AES 2 */
+               .key    = "\x11\x11\x11\x11\x11\x11\x11\x11"
+                         "\x11\x11\x11\x11\x11\x11\x11\x11"
+                         "\x22\x22\x22\x22\x22\x22\x22\x22"
+                         "\x22\x22\x22\x22\x22\x22\x22\x22",
+               .klen   = 32,
+               .iv     = "\x33\x33\x33\x33\x33\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "\xc4\x54\x18\x5e\x6a\x16\x93\x6e"
+                         "\x39\x33\x40\x38\xac\xef\x83\x8b"
+                         "\xfb\x18\x6f\xff\x74\x80\xad\xc4"
+                         "\x28\x93\x82\xec\xd6\xd3\x94\xf0",
+               .ilen   = 32,
+               .result = "\x44\x44\x44\x44\x44\x44\x44\x44"
+                         "\x44\x44\x44\x44\x44\x44\x44\x44"
+                         "\x44\x44\x44\x44\x44\x44\x44\x44"
+                         "\x44\x44\x44\x44\x44\x44\x44\x44",
+               .rlen   = 32,
+       }, { /* XTS-AES 3 */
+               .key    = "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8"
+                         "\xf7\xf6\xf5\xf4\xf3\xf2\xf1\xf0"
+                         "\x22\x22\x22\x22\x22\x22\x22\x22"
+                         "\x22\x22\x22\x22\x22\x22\x22\x22",
+               .klen   = 32,
+               .iv     = "\x33\x33\x33\x33\x33\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input = "\xaf\x85\x33\x6b\x59\x7a\xfc\x1a"
+                         "\x90\x0b\x2e\xb2\x1e\xc9\x49\xd2"
+                         "\x92\xdf\x4c\x04\x7e\x0b\x21\x53"
+                         "\x21\x86\xa5\x97\x1a\x22\x7a\x89",
+               .ilen   = 32,
+               .result  = "\x44\x44\x44\x44\x44\x44\x44\x44"
+                         "\x44\x44\x44\x44\x44\x44\x44\x44"
+                         "\x44\x44\x44\x44\x44\x44\x44\x44"
+                         "\x44\x44\x44\x44\x44\x44\x44\x44",
+               .rlen   = 32,
+       }, { /* XTS-AES 4 */
+               .key    = "\x27\x18\x28\x18\x28\x45\x90\x45"
+                         "\x23\x53\x60\x28\x74\x71\x35\x26"
+                         "\x31\x41\x59\x26\x53\x58\x97\x93"
+                         "\x23\x84\x62\x64\x33\x83\x27\x95",
+               .klen   = 32,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "\x27\xa7\x47\x9b\xef\xa1\xd4\x76"
+                         "\x48\x9f\x30\x8c\xd4\xcf\xa6\xe2"
+                         "\xa9\x6e\x4b\xbe\x32\x08\xff\x25"
+                         "\x28\x7d\xd3\x81\x96\x16\xe8\x9c"
+                         "\xc7\x8c\xf7\xf5\xe5\x43\x44\x5f"
+                         "\x83\x33\xd8\xfa\x7f\x56\x00\x00"
+                         "\x05\x27\x9f\xa5\xd8\xb5\xe4\xad"
+                         "\x40\xe7\x36\xdd\xb4\xd3\x54\x12"
+                         "\x32\x80\x63\xfd\x2a\xab\x53\xe5"
+                         "\xea\x1e\x0a\x9f\x33\x25\x00\xa5"
+                         "\xdf\x94\x87\xd0\x7a\x5c\x92\xcc"
+                         "\x51\x2c\x88\x66\xc7\xe8\x60\xce"
+                         "\x93\xfd\xf1\x66\xa2\x49\x12\xb4"
+                         "\x22\x97\x61\x46\xae\x20\xce\x84"
+                         "\x6b\xb7\xdc\x9b\xa9\x4a\x76\x7a"
+                         "\xae\xf2\x0c\x0d\x61\xad\x02\x65"
+                         "\x5e\xa9\x2d\xc4\xc4\xe4\x1a\x89"
+                         "\x52\xc6\x51\xd3\x31\x74\xbe\x51"
+                         "\xa1\x0c\x42\x11\x10\xe6\xd8\x15"
+                         "\x88\xed\xe8\x21\x03\xa2\x52\xd8"
+                         "\xa7\x50\xe8\x76\x8d\xef\xff\xed"
+                         "\x91\x22\x81\x0a\xae\xb9\x9f\x91"
+                         "\x72\xaf\x82\xb6\x04\xdc\x4b\x8e"
+                         "\x51\xbc\xb0\x82\x35\xa6\xf4\x34"
+                         "\x13\x32\xe4\xca\x60\x48\x2a\x4b"
+                         "\xa1\xa0\x3b\x3e\x65\x00\x8f\xc5"
+                         "\xda\x76\xb7\x0b\xf1\x69\x0d\xb4"
+                         "\xea\xe2\x9c\x5f\x1b\xad\xd0\x3c"
+                         "\x5c\xcf\x2a\x55\xd7\x05\xdd\xcd"
+                         "\x86\xd4\x49\x51\x1c\xeb\x7e\xc3"
+                         "\x0b\xf1\x2b\x1f\xa3\x5b\x91\x3f"
+                         "\x9f\x74\x7a\x8a\xfd\x1b\x13\x0e"
+                         "\x94\xbf\xf9\x4e\xff\xd0\x1a\x91"
+                         "\x73\x5c\xa1\x72\x6a\xcd\x0b\x19"
+                         "\x7c\x4e\x5b\x03\x39\x36\x97\xe1"
+                         "\x26\x82\x6f\xb6\xbb\xde\x8e\xcc"
+                         "\x1e\x08\x29\x85\x16\xe2\xc9\xed"
+                         "\x03\xff\x3c\x1b\x78\x60\xf6\xde"
+                         "\x76\xd4\xce\xcd\x94\xc8\x11\x98"
+                         "\x55\xef\x52\x97\xca\x67\xe9\xf3"
+                         "\xe7\xff\x72\xb1\xe9\x97\x85\xca"
+                         "\x0a\x7e\x77\x20\xc5\xb3\x6d\xc6"
+                         "\xd7\x2c\xac\x95\x74\xc8\xcb\xbc"
+                         "\x2f\x80\x1e\x23\xe5\x6f\xd3\x44"
+                         "\xb0\x7f\x22\x15\x4b\xeb\xa0\xf0"
+                         "\x8c\xe8\x89\x1e\x64\x3e\xd9\x95"
+                         "\xc9\x4d\x9a\x69\xc9\xf1\xb5\xf4"
+                         "\x99\x02\x7a\x78\x57\x2a\xee\xbd"
+                         "\x74\xd2\x0c\xc3\x98\x81\xc2\x13"
+                         "\xee\x77\x0b\x10\x10\xe4\xbe\xa7"
+                         "\x18\x84\x69\x77\xae\x11\x9f\x7a"
+                         "\x02\x3a\xb5\x8c\xca\x0a\xd7\x52"
+                         "\xaf\xe6\x56\xbb\x3c\x17\x25\x6a"
+                         "\x9f\x6e\x9b\xf1\x9f\xdd\x5a\x38"
+                         "\xfc\x82\xbb\xe8\x72\xc5\x53\x9e"
+                         "\xdb\x60\x9e\xf4\xf7\x9c\x20\x3e"
+                         "\xbb\x14\x0f\x2e\x58\x3c\xb2\xad"
+                         "\x15\xb4\xaa\x5b\x65\x50\x16\xa8"
+                         "\x44\x92\x77\xdb\xd4\x77\xef\x2c"
+                         "\x8d\x6c\x01\x7d\xb7\x38\xb1\x8d"
+                         "\xeb\x4a\x42\x7d\x19\x23\xce\x3f"
+                         "\xf2\x62\x73\x57\x79\xa4\x18\xf2"
+                         "\x0a\x28\x2d\xf9\x20\x14\x7b\xea"
+                         "\xbe\x42\x1e\xe5\x31\x9d\x05\x68",
+               .ilen   = 512,
+               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+                         "\x20\x21\x22\x23\x24\x25\x26\x27"
+                         "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+                         "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+                         "\x40\x41\x42\x43\x44\x45\x46\x47"
+                         "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+                         "\x50\x51\x52\x53\x54\x55\x56\x57"
+                         "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+                         "\x60\x61\x62\x63\x64\x65\x66\x67"
+                         "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+                         "\x70\x71\x72\x73\x74\x75\x76\x77"
+                         "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+                         "\x80\x81\x82\x83\x84\x85\x86\x87"
+                         "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+                         "\x90\x91\x92\x93\x94\x95\x96\x97"
+                         "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+                         "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+                         "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+                         "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+                         "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+                         "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+                         "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+                         "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+                         "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+                         "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+                         "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+                         "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
+                         "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+                         "\x20\x21\x22\x23\x24\x25\x26\x27"
+                         "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+                         "\x30\x31\x32\x33\x34\x35\x36\x37"
+                         "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+                         "\x40\x41\x42\x43\x44\x45\x46\x47"
+                         "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+                         "\x50\x51\x52\x53\x54\x55\x56\x57"
+                         "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+                         "\x60\x61\x62\x63\x64\x65\x66\x67"
+                         "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+                         "\x70\x71\x72\x73\x74\x75\x76\x77"
+                         "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+                         "\x80\x81\x82\x83\x84\x85\x86\x87"
+                         "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+                         "\x90\x91\x92\x93\x94\x95\x96\x97"
+                         "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+                         "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+                         "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+                         "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+                         "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+                         "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+                         "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+                         "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+                         "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+                         "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+                         "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+                         "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+               .rlen   = 512,
+       }
+};
+
+
+static struct cipher_testvec aes_ctr_enc_tv_template[] = {
+       { /* From RFC 3686 */
+               .key    = "\xae\x68\x52\xf8\x12\x10\x67\xcc"
+                         "\x4b\xf7\xa5\x76\x55\x77\xf3\x9e"
+                         "\x00\x00\x00\x30",
+               .klen   = 20,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "Single block msg",
+               .ilen   = 16,
+               .result = "\xe4\x09\x5d\x4f\xb7\xa7\xb3\x79"
+                         "\x2d\x61\x75\xa3\x26\x13\x11\xb8",
+               .rlen   = 16,
+       }, {
+               .key    = "\x7e\x24\x06\x78\x17\xfa\xe0\xd7"
+                         "\x43\xd6\xce\x1f\x32\x53\x91\x63"
+                         "\x00\x6c\xb6\xdb",
+               .klen   = 20,
+               .iv     = "\xc0\x54\x3b\x59\xda\x48\xd9\x0b",
+               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .ilen   = 32,
+               .result = "\x51\x04\xa1\x06\x16\x8a\x72\xd9"
+                         "\x79\x0d\x41\xee\x8e\xda\xd3\x88"
+                         "\xeb\x2e\x1e\xfc\x46\xda\x57\xc8"
+                         "\xfc\xe6\x30\xdf\x91\x41\xbe\x28",
+               .rlen   = 32,
+       }, {
+               .key    = "\x16\xaf\x5b\x14\x5f\xc9\xf5\x79"
+                         "\xc1\x75\xf9\x3e\x3b\xfb\x0e\xed"
+                         "\x86\x3d\x06\xcc\xfd\xb7\x85\x15"
+                         "\x00\x00\x00\x48",
+               .klen   = 28,
+               .iv     = "\x36\x73\x3c\x14\x7d\x6d\x93\xcb",
+               .input  = "Single block msg",
+               .ilen   = 16,
+               .result = "\x4b\x55\x38\x4f\xe2\x59\xc9\xc8"
+                         "\x4e\x79\x35\xa0\x03\xcb\xe9\x28",
+               .rlen   = 16,
+       }, {
+               .key    = "\x7c\x5c\xb2\x40\x1b\x3d\xc3\x3c"
+                         "\x19\xe7\x34\x08\x19\xe0\xf6\x9c"
+                         "\x67\x8c\x3d\xb8\xe6\xf6\xa9\x1a"
+                         "\x00\x96\xb0\x3b",
+               .klen   = 28,
+               .iv     = "\x02\x0c\x6e\xad\xc2\xcb\x50\x0d",
+               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .ilen   = 32,
+               .result = "\x45\x32\x43\xfc\x60\x9b\x23\x32"
+                         "\x7e\xdf\xaa\xfa\x71\x31\xcd\x9f"
+                         "\x84\x90\x70\x1c\x5a\xd4\xa7\x9c"
+                         "\xfc\x1f\xe0\xff\x42\xf4\xfb\x00",
+               .rlen   = 32,
+       }, {
+               .key    = "\x77\x6b\xef\xf2\x85\x1d\xb0\x6f"
+                         "\x4c\x8a\x05\x42\xc8\x69\x6f\x6c"
+                         "\x6a\x81\xaf\x1e\xec\x96\xb4\xd3"
+                         "\x7f\xc1\xd6\x89\xe6\xc1\xc1\x04"
+                         "\x00\x00\x00\x60",
+               .klen   = 36,
+               .iv     = "\xdb\x56\x72\xc9\x7a\xa8\xf0\xb2",
+               .input  = "Single block msg",
+               .ilen   = 16,
+               .result = "\x14\x5a\xd0\x1d\xbf\x82\x4e\xc7"
+                         "\x56\x08\x63\xdc\x71\xe3\xe0\xc0",
+               .rlen   = 16,
+       }, {
+               .key    = "\xf6\xd6\x6d\x6b\xd5\x2d\x59\xbb"
+                         "\x07\x96\x36\x58\x79\xef\xf8\x86"
+                         "\xc6\x6d\xd5\x1a\x5b\x6a\x99\x74"
+                         "\x4b\x50\x59\x0c\x87\xa2\x38\x84"
+                         "\x00\xfa\xac\x24",
+               .klen   = 36,
+               .iv     = "\xc1\x58\x5e\xf1\x5a\x43\xd8\x75",
+               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .ilen   = 32,
+               .result = "\xf0\x5e\x23\x1b\x38\x94\x61\x2c"
+                         "\x49\xee\x00\x0b\x80\x4e\xb2\xa9"
+                         "\xb8\x30\x6b\x50\x8f\x83\x9d\x6a"
+                         "\x55\x30\x83\x1d\x93\x44\xaf\x1c",
+               .rlen   = 32,
+       }, {
+       // generated using Crypto++
+               .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                       "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                       "\x10\x11\x12\x13\x14\x15\x16\x17"
+                       "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+                       "\x00\x00\x00\x00",
+               .klen = 32 + 4,
+               .iv = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input =
+                       "\x00\x01\x02\x03\x04\x05\x06\x07"
+                       "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                       "\x10\x11\x12\x13\x14\x15\x16\x17"
+                       "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+                       "\x20\x21\x22\x23\x24\x25\x26\x27"
+                       "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+                       "\x30\x31\x32\x33\x34\x35\x36\x37"
+                       "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+                       "\x40\x41\x42\x43\x44\x45\x46\x47"
+                       "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+                       "\x50\x51\x52\x53\x54\x55\x56\x57"
+                       "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+                       "\x60\x61\x62\x63\x64\x65\x66\x67"
+                       "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+                       "\x70\x71\x72\x73\x74\x75\x76\x77"
+                       "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+                       "\x80\x81\x82\x83\x84\x85\x86\x87"
+                       "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+                       "\x90\x91\x92\x93\x94\x95\x96\x97"
+                       "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+                       "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+                       "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+                       "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+                       "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+                       "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+                       "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+                       "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+                       "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+                       "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+                       "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+                       "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+                       "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
+                       "\x00\x03\x06\x09\x0c\x0f\x12\x15"
+                       "\x18\x1b\x1e\x21\x24\x27\x2a\x2d"
+                       "\x30\x33\x36\x39\x3c\x3f\x42\x45"
+                       "\x48\x4b\x4e\x51\x54\x57\x5a\x5d"
+                       "\x60\x63\x66\x69\x6c\x6f\x72\x75"
+                       "\x78\x7b\x7e\x81\x84\x87\x8a\x8d"
+                       "\x90\x93\x96\x99\x9c\x9f\xa2\xa5"
+                       "\xa8\xab\xae\xb1\xb4\xb7\xba\xbd"
+                       "\xc0\xc3\xc6\xc9\xcc\xcf\xd2\xd5"
+                       "\xd8\xdb\xde\xe1\xe4\xe7\xea\xed"
+                       "\xf0\xf3\xf6\xf9\xfc\xff\x02\x05"
+                       "\x08\x0b\x0e\x11\x14\x17\x1a\x1d"
+                       "\x20\x23\x26\x29\x2c\x2f\x32\x35"
+                       "\x38\x3b\x3e\x41\x44\x47\x4a\x4d"
+                       "\x50\x53\x56\x59\x5c\x5f\x62\x65"
+                       "\x68\x6b\x6e\x71\x74\x77\x7a\x7d"
+                       "\x80\x83\x86\x89\x8c\x8f\x92\x95"
+                       "\x98\x9b\x9e\xa1\xa4\xa7\xaa\xad"
+                       "\xb0\xb3\xb6\xb9\xbc\xbf\xc2\xc5"
+                       "\xc8\xcb\xce\xd1\xd4\xd7\xda\xdd"
+                       "\xe0\xe3\xe6\xe9\xec\xef\xf2\xf5"
+                       "\xf8\xfb\xfe\x01\x04\x07\x0a\x0d"
+                       "\x10\x13\x16\x19\x1c\x1f\x22\x25"
+                       "\x28\x2b\x2e\x31\x34\x37\x3a\x3d"
+                       "\x40\x43\x46\x49\x4c\x4f\x52\x55"
+                       "\x58\x5b\x5e\x61\x64\x67\x6a\x6d"
+                       "\x70\x73\x76\x79\x7c\x7f\x82\x85"
+                       "\x88\x8b\x8e\x91\x94\x97\x9a\x9d"
+                       "\xa0\xa3\xa6\xa9\xac\xaf\xb2\xb5"
+                       "\xb8\xbb\xbe\xc1\xc4\xc7\xca\xcd"
+                       "\xd0\xd3\xd6\xd9\xdc\xdf\xe2\xe5"
+                       "\xe8\xeb\xee\xf1\xf4\xf7\xfa\xfd"
+                       "\x00\x05\x0a\x0f\x14\x19\x1e\x23"
+                       "\x28\x2d\x32\x37\x3c\x41\x46\x4b"
+                       "\x50\x55\x5a\x5f\x64\x69\x6e\x73"
+                       "\x78\x7d\x82\x87\x8c\x91\x96\x9b"
+                       "\xa0\xa5\xaa\xaf\xb4\xb9\xbe\xc3"
+                       "\xc8\xcd\xd2\xd7\xdc\xe1\xe6\xeb"
+                       "\xf0\xf5\xfa\xff\x04\x09\x0e\x13"
+                       "\x18\x1d\x22\x27\x2c\x31\x36\x3b"
+                       "\x40\x45\x4a\x4f\x54\x59\x5e\x63"
+                       "\x68\x6d\x72\x77\x7c\x81\x86\x8b"
+                       "\x90\x95\x9a\x9f\xa4\xa9\xae\xb3"
+                       "\xb8\xbd\xc2\xc7\xcc\xd1\xd6\xdb"
+                       "\xe0\xe5\xea\xef\xf4\xf9\xfe\x03"
+                       "\x08\x0d\x12\x17\x1c\x21\x26\x2b"
+                       "\x30\x35\x3a\x3f\x44\x49\x4e\x53"
+                       "\x58\x5d\x62\x67\x6c\x71\x76\x7b"
+                       "\x80\x85\x8a\x8f\x94\x99\x9e\xa3"
+                       "\xa8\xad\xb2\xb7\xbc\xc1\xc6\xcb"
+                       "\xd0\xd5\xda\xdf\xe4\xe9\xee\xf3"
+                       "\xf8\xfd\x02\x07\x0c\x11\x16\x1b"
+                       "\x20\x25\x2a\x2f\x34\x39\x3e\x43"
+                       "\x48\x4d\x52\x57\x5c\x61\x66\x6b"
+                       "\x70\x75\x7a\x7f\x84\x89\x8e\x93"
+                       "\x98\x9d\xa2\xa7\xac\xb1\xb6\xbb"
+                       "\xc0\xc5\xca\xcf\xd4\xd9\xde\xe3"
+                       "\xe8\xed\xf2\xf7\xfc\x01\x06\x0b"
+                       "\x10\x15\x1a\x1f\x24\x29\x2e\x33"
+                       "\x38\x3d\x42\x47\x4c\x51\x56\x5b"
+                       "\x60\x65\x6a\x6f\x74\x79\x7e\x83"
+                       "\x88\x8d\x92\x97\x9c\xa1\xa6\xab"
+                       "\xb0\xb5\xba\xbf\xc4\xc9\xce\xd3"
+                       "\xd8\xdd\xe2\xe7\xec\xf1\xf6\xfb"
+                       "\x00\x07\x0e\x15\x1c\x23\x2a\x31"
+                       "\x38\x3f\x46\x4d\x54\x5b\x62\x69"
+                       "\x70\x77\x7e\x85\x8c\x93\x9a\xa1"
+                       "\xa8\xaf\xb6\xbd\xc4\xcb\xd2\xd9"
+                       "\xe0\xe7\xee\xf5\xfc\x03\x0a\x11"
+                       "\x18\x1f\x26\x2d\x34\x3b\x42\x49"
+                       "\x50\x57\x5e\x65\x6c\x73\x7a\x81"
+                       "\x88\x8f\x96\x9d\xa4\xab\xb2\xb9"
+                       "\xc0\xc7\xce\xd5\xdc\xe3\xea\xf1"
+                       "\xf8\xff\x06\x0d\x14\x1b\x22\x29"
+                       "\x30\x37\x3e\x45\x4c\x53\x5a\x61"
+                       "\x68\x6f\x76\x7d\x84\x8b\x92\x99"
+                       "\xa0\xa7\xae\xb5\xbc\xc3\xca\xd1"
+                       "\xd8\xdf\xe6\xed\xf4\xfb\x02\x09"
+                       "\x10\x17\x1e\x25\x2c\x33\x3a\x41"
+                       "\x48\x4f\x56\x5d\x64\x6b\x72\x79"
+                       "\x80\x87\x8e\x95\x9c\xa3\xaa\xb1"
+                       "\xb8\xbf\xc6\xcd\xd4\xdb\xe2\xe9"
+                       "\xf0\xf7\xfe\x05\x0c\x13\x1a\x21"
+                       "\x28\x2f\x36\x3d\x44\x4b\x52\x59"
+                       "\x60\x67\x6e\x75\x7c\x83\x8a\x91"
+                       "\x98\x9f\xa6\xad\xb4\xbb\xc2\xc9"
+                       "\xd0\xd7\xde\xe5\xec\xf3\xfa\x01"
+                       "\x08\x0f\x16\x1d\x24\x2b\x32\x39"
+                       "\x40\x47\x4e\x55\x5c\x63\x6a\x71"
+                       "\x78\x7f\x86\x8d\x94\x9b\xa2\xa9"
+                       "\xb0\xb7\xbe\xc5\xcc\xd3\xda\xe1"
+                       "\xe8\xef\xf6\xfd\x04\x0b\x12\x19"
+                       "\x20\x27\x2e\x35\x3c\x43\x4a\x51"
+                       "\x58\x5f\x66\x6d\x74\x7b\x82\x89"
+                       "\x90\x97\x9e\xa5\xac\xb3\xba\xc1"
+                       "\xc8\xcf\xd6\xdd\xe4\xeb\xf2\xf9"
+                       "\x00\x09\x12\x1b\x24\x2d\x36\x3f"
+                       "\x48\x51\x5a\x63\x6c\x75\x7e\x87"
+                       "\x90\x99\xa2\xab\xb4\xbd\xc6\xcf"
+                       "\xd8\xe1\xea\xf3\xfc\x05\x0e\x17"
+                       "\x20\x29\x32\x3b\x44\x4d\x56\x5f"
+                       "\x68\x71\x7a\x83\x8c\x95\x9e\xa7"
+                       "\xb0\xb9\xc2\xcb\xd4\xdd\xe6\xef"
+                       "\xf8\x01\x0a\x13\x1c\x25\x2e\x37"
+                       "\x40\x49\x52\x5b\x64\x6d\x76\x7f"
+                       "\x88\x91\x9a\xa3\xac\xb5\xbe\xc7"
+                       "\xd0\xd9\xe2\xeb\xf4\xfd\x06\x0f"
+                       "\x18\x21\x2a\x33\x3c\x45\x4e\x57"
+                       "\x60\x69\x72\x7b\x84\x8d\x96\x9f"
+                       "\xa8\xb1\xba\xc3\xcc\xd5\xde\xe7"
+                       "\xf0\xf9\x02\x0b\x14\x1d\x26\x2f"
+                       "\x38\x41\x4a\x53\x5c\x65\x6e\x77"
+                       "\x80\x89\x92\x9b\xa4\xad\xb6\xbf"
+                       "\xc8\xd1\xda\xe3\xec\xf5\xfe\x07"
+                       "\x10\x19\x22\x2b\x34\x3d\x46\x4f"
+                       "\x58\x61\x6a\x73\x7c\x85\x8e\x97"
+                       "\xa0\xa9\xb2\xbb\xc4\xcd\xd6\xdf"
+                       "\xe8\xf1\xfa\x03\x0c\x15\x1e\x27"
+                       "\x30\x39\x42\x4b\x54\x5d\x66\x6f"
+                       "\x78\x81\x8a\x93\x9c\xa5\xae\xb7"
+                       "\xc0\xc9\xd2\xdb\xe4\xed\xf6\xff"
+                       "\x08\x11\x1a\x23\x2c\x35\x3e\x47"
+                       "\x50\x59\x62\x6b\x74\x7d\x86\x8f"
+                       "\x98\xa1\xaa\xb3\xbc\xc5\xce\xd7"
+                       "\xe0\xe9\xf2\xfb\x04\x0d\x16\x1f"
+                       "\x28\x31\x3a\x43\x4c\x55\x5e\x67"
+                       "\x70\x79\x82\x8b\x94\x9d\xa6\xaf"
+                       "\xb8\xc1\xca\xd3\xdc\xe5\xee\xf7"
+                       "\x00\x0b\x16\x21\x2c\x37\x42\x4d"
+                       "\x58\x63\x6e\x79\x84\x8f\x9a\xa5"
+                       "\xb0\xbb\xc6\xd1\xdc\xe7\xf2\xfd"
+                       "\x08\x13\x1e\x29\x34\x3f\x4a\x55"
+                       "\x60\x6b\x76\x81\x8c\x97\xa2\xad"
+                       "\xb8\xc3\xce\xd9\xe4\xef\xfa\x05"
+                       "\x10\x1b\x26\x31\x3c\x47\x52\x5d"
+                       "\x68\x73\x7e\x89\x94\x9f\xaa\xb5"
+                       "\xc0\xcb\xd6\xe1\xec\xf7\x02\x0d"
+                       "\x18\x23\x2e\x39\x44\x4f\x5a\x65"
+                       "\x70\x7b\x86\x91\x9c\xa7\xb2\xbd"
+                       "\xc8\xd3\xde\xe9\xf4\xff\x0a\x15"
+                       "\x20\x2b\x36\x41\x4c\x57\x62\x6d"
+                       "\x78\x83\x8e\x99\xa4\xaf\xba\xc5"
+                       "\xd0\xdb\xe6\xf1\xfc\x07\x12\x1d"
+                       "\x28\x33\x3e\x49\x54\x5f\x6a\x75"
+                       "\x80\x8b\x96\xa1\xac\xb7\xc2\xcd"
+                       "\xd8\xe3\xee\xf9\x04\x0f\x1a\x25"
+                       "\x30\x3b\x46\x51\x5c\x67\x72\x7d"
+                       "\x88\x93\x9e\xa9\xb4\xbf\xca\xd5"
+                       "\xe0\xeb\xf6\x01\x0c\x17\x22\x2d"
+                       "\x38\x43\x4e\x59\x64\x6f\x7a\x85"
+                       "\x90\x9b\xa6\xb1\xbc\xc7\xd2\xdd"
+                       "\xe8\xf3\xfe\x09\x14\x1f\x2a\x35"
+                       "\x40\x4b\x56\x61\x6c\x77\x82\x8d"
+                       "\x98\xa3\xae\xb9\xc4\xcf\xda\xe5"
+                       "\xf0\xfb\x06\x11\x1c\x27\x32\x3d"
+                       "\x48\x53\x5e\x69\x74\x7f\x8a\x95"
+                       "\xa0\xab\xb6\xc1\xcc\xd7\xe2\xed"
+                       "\xf8\x03\x0e\x19\x24\x2f\x3a\x45"
+                       "\x50\x5b\x66\x71\x7c\x87\x92\x9d"
+                       "\xa8\xb3\xbe\xc9\xd4\xdf\xea\xf5"
+                       "\x00\x0d\x1a\x27\x34\x41\x4e\x5b"
+                       "\x68\x75\x82\x8f\x9c\xa9\xb6\xc3"
+                       "\xd0\xdd\xea\xf7\x04\x11\x1e\x2b"
+                       "\x38\x45\x52\x5f\x6c\x79\x86\x93"
+                       "\xa0\xad\xba\xc7\xd4\xe1\xee\xfb"
+                       "\x08\x15\x22\x2f\x3c\x49\x56\x63"
+                       "\x70\x7d\x8a\x97\xa4\xb1\xbe\xcb"
+                       "\xd8\xe5\xf2\xff\x0c\x19\x26\x33"
+                       "\x40\x4d\x5a\x67\x74\x81\x8e\x9b"
+                       "\xa8\xb5\xc2\xcf\xdc\xe9\xf6\x03"
+                       "\x10\x1d\x2a\x37\x44\x51\x5e\x6b"
+                       "\x78\x85\x92\x9f\xac\xb9\xc6\xd3"
+                       "\xe0\xed\xfa\x07\x14\x21\x2e\x3b"
+                       "\x48\x55\x62\x6f\x7c\x89\x96\xa3"
+                       "\xb0\xbd\xca\xd7\xe4\xf1\xfe\x0b"
+                       "\x18\x25\x32\x3f\x4c\x59\x66\x73"
+                       "\x80\x8d\x9a\xa7\xb4\xc1\xce\xdb"
+                       "\xe8\xf5\x02\x0f\x1c\x29\x36\x43"
+                       "\x50\x5d\x6a\x77\x84\x91\x9e\xab"
+                       "\xb8\xc5\xd2\xdf\xec\xf9\x06\x13"
+                       "\x20\x2d\x3a\x47\x54\x61\x6e\x7b"
+                       "\x88\x95\xa2\xaf\xbc\xc9\xd6\xe3"
+                       "\xf0\xfd\x0a\x17\x24\x31\x3e\x4b"
+                       "\x58\x65\x72\x7f\x8c\x99\xa6\xb3"
+                       "\xc0\xcd\xda\xe7\xf4\x01\x0e\x1b"
+                       "\x28\x35\x42\x4f\x5c\x69\x76\x83"
+                       "\x90\x9d\xaa\xb7\xc4\xd1\xde\xeb"
+                       "\xf8\x05\x12\x1f\x2c\x39\x46\x53"
+                       "\x60\x6d\x7a\x87\x94\xa1\xae\xbb"
+                       "\xc8\xd5\xe2\xef\xfc\x09\x16\x23"
+                       "\x30\x3d\x4a\x57\x64\x71\x7e\x8b"
+                       "\x98\xa5\xb2\xbf\xcc\xd9\xe6\xf3"
+                       "\x00\x0f\x1e\x2d\x3c\x4b\x5a\x69"
+                       "\x78\x87\x96\xa5\xb4\xc3\xd2\xe1"
+                       "\xf0\xff\x0e\x1d\x2c\x3b\x4a\x59"
+                       "\x68\x77\x86\x95\xa4\xb3\xc2\xd1"
+                       "\xe0\xef\xfe\x0d\x1c\x2b\x3a\x49"
+                       "\x58\x67\x76\x85\x94\xa3\xb2\xc1"
+                       "\xd0\xdf\xee\xfd\x0c\x1b\x2a\x39"
+                       "\x48\x57\x66\x75\x84\x93\xa2\xb1"
+                       "\xc0\xcf\xde\xed\xfc\x0b\x1a\x29"
+                       "\x38\x47\x56\x65\x74\x83\x92\xa1"
+                       "\xb0\xbf\xce\xdd\xec\xfb\x0a\x19"
+                       "\x28\x37\x46\x55\x64\x73\x82\x91"
+                       "\xa0\xaf\xbe\xcd\xdc\xeb\xfa\x09"
+                       "\x18\x27\x36\x45\x54\x63\x72\x81"
+                       "\x90\x9f\xae\xbd\xcc\xdb\xea\xf9"
+                       "\x08\x17\x26\x35\x44\x53\x62\x71"
+                       "\x80\x8f\x9e\xad\xbc\xcb\xda\xe9"
+                       "\xf8\x07\x16\x25\x34\x43\x52\x61"
+                       "\x70\x7f\x8e\x9d\xac\xbb\xca\xd9"
+                       "\xe8\xf7\x06\x15\x24\x33\x42\x51"
+                       "\x60\x6f\x7e\x8d\x9c\xab\xba\xc9"
+                       "\xd8\xe7\xf6\x05\x14\x23\x32\x41"
+                       "\x50\x5f\x6e\x7d\x8c\x9b\xaa\xb9"
+                       "\xc8\xd7\xe6\xf5\x04\x13\x22\x31"
+                       "\x40\x4f\x5e\x6d\x7c\x8b\x9a\xa9"
+                       "\xb8\xc7\xd6\xe5\xf4\x03\x12\x21"
+                       "\x30\x3f\x4e\x5d\x6c\x7b\x8a\x99"
+                       "\xa8\xb7\xc6\xd5\xe4\xf3\x02\x11"
+                       "\x20\x2f\x3e\x4d\x5c\x6b\x7a\x89"
+                       "\x98\xa7\xb6\xc5\xd4\xe3\xf2\x01"
+                       "\x10\x1f\x2e\x3d\x4c\x5b\x6a\x79"
+                       "\x88\x97\xa6\xb5\xc4\xd3\xe2\xf1"
+                       "\x00\x11\x22\x33\x44\x55\x66\x77"
+                       "\x88\x99\xaa\xbb\xcc\xdd\xee\xff"
+                       "\x10\x21\x32\x43\x54\x65\x76\x87"
+                       "\x98\xa9\xba\xcb\xdc\xed\xfe\x0f"
+                       "\x20\x31\x42\x53\x64\x75\x86\x97"
+                       "\xa8\xb9\xca\xdb\xec\xfd\x0e\x1f"
+                       "\x30\x41\x52\x63\x74\x85\x96\xa7"
+                       "\xb8\xc9\xda\xeb\xfc\x0d\x1e\x2f"
+                       "\x40\x51\x62\x73\x84\x95\xa6\xb7"
+                       "\xc8\xd9\xea\xfb\x0c\x1d\x2e\x3f"
+                       "\x50\x61\x72\x83\x94\xa5\xb6\xc7"
+                       "\xd8\xe9\xfa\x0b\x1c\x2d\x3e\x4f"
+                       "\x60\x71\x82\x93\xa4\xb5\xc6\xd7"
+                       "\xe8\xf9\x0a\x1b\x2c\x3d\x4e\x5f"
+                       "\x70\x81\x92\xa3\xb4\xc5\xd6\xe7"
+                       "\xf8\x09\x1a\x2b\x3c\x4d\x5e\x6f"
+                       "\x80\x91\xa2\xb3\xc4\xd5\xe6\xf7"
+                       "\x08\x19\x2a\x3b\x4c\x5d\x6e\x7f"
+                       "\x90\xa1\xb2\xc3\xd4\xe5\xf6\x07"
+                       "\x18\x29\x3a\x4b\x5c\x6d\x7e\x8f"
+                       "\xa0\xb1\xc2\xd3\xe4\xf5\x06\x17"
+                       "\x28\x39\x4a\x5b\x6c\x7d\x8e\x9f"
+                       "\xb0\xc1\xd2\xe3\xf4\x05\x16\x27"
+                       "\x38\x49\x5a\x6b\x7c\x8d\x9e\xaf"
+                       "\xc0\xd1\xe2\xf3\x04\x15\x26\x37"
+                       "\x48\x59\x6a\x7b\x8c\x9d\xae\xbf"
+                       "\xd0\xe1\xf2\x03\x14\x25\x36\x47"
+                       "\x58\x69\x7a\x8b\x9c\xad\xbe\xcf"
+                       "\xe0\xf1\x02\x13\x24\x35\x46\x57"
+                       "\x68\x79\x8a\x9b\xac\xbd\xce\xdf"
+                       "\xf0\x01\x12\x23\x34\x45\x56\x67"
+                       "\x78\x89\x9a\xab\xbc\xcd\xde\xef"
+                       "\x00\x13\x26\x39\x4c\x5f\x72\x85"
+                       "\x98\xab\xbe\xd1\xe4\xf7\x0a\x1d"
+                       "\x30\x43\x56\x69\x7c\x8f\xa2\xb5"
+                       "\xc8\xdb\xee\x01\x14\x27\x3a\x4d"
+                       "\x60\x73\x86\x99\xac\xbf\xd2\xe5"
+                       "\xf8\x0b\x1e\x31\x44\x57\x6a\x7d"
+                       "\x90\xa3\xb6\xc9\xdc\xef\x02\x15"
+                       "\x28\x3b\x4e\x61\x74\x87\x9a\xad"
+                       "\xc0\xd3\xe6\xf9\x0c\x1f\x32\x45"
+                       "\x58\x6b\x7e\x91\xa4\xb7\xca\xdd"
+                       "\xf0\x03\x16\x29\x3c\x4f\x62\x75"
+                       "\x88\x9b\xae\xc1\xd4\xe7\xfa\x0d"
+                       "\x20\x33\x46\x59\x6c\x7f\x92\xa5"
+                       "\xb8\xcb\xde\xf1\x04\x17\x2a\x3d"
+                       "\x50\x63\x76\x89\x9c\xaf\xc2\xd5"
+                       "\xe8\xfb\x0e\x21\x34\x47\x5a\x6d"
+                       "\x80\x93\xa6\xb9\xcc\xdf\xf2\x05"
+                       "\x18\x2b\x3e\x51\x64\x77\x8a\x9d"
+                       "\xb0\xc3\xd6\xe9\xfc\x0f\x22\x35"
+                       "\x48\x5b\x6e\x81\x94\xa7\xba\xcd"
+                       "\xe0\xf3\x06\x19\x2c\x3f\x52\x65"
+                       "\x78\x8b\x9e\xb1\xc4\xd7\xea\xfd"
+                       "\x10\x23\x36\x49\x5c\x6f\x82\x95"
+                       "\xa8\xbb\xce\xe1\xf4\x07\x1a\x2d"
+                       "\x40\x53\x66\x79\x8c\x9f\xb2\xc5"
+                       "\xd8\xeb\xfe\x11\x24\x37\x4a\x5d"
+                       "\x70\x83\x96\xa9\xbc\xcf\xe2\xf5"
+                       "\x08\x1b\x2e\x41\x54\x67\x7a\x8d"
+                       "\xa0\xb3\xc6\xd9\xec\xff\x12\x25"
+                       "\x38\x4b\x5e\x71\x84\x97\xaa\xbd"
+                       "\xd0\xe3\xf6\x09\x1c\x2f\x42\x55"
+                       "\x68\x7b\x8e\xa1\xb4\xc7\xda\xed"
+                       "\x00\x15\x2a\x3f\x54\x69\x7e\x93"
+                       "\xa8\xbd\xd2\xe7\xfc\x11\x26\x3b"
+                       "\x50\x65\x7a\x8f\xa4\xb9\xce\xe3"
+                       "\xf8\x0d\x22\x37\x4c\x61\x76\x8b"
+                       "\xa0\xb5\xca\xdf\xf4\x09\x1e\x33"
+                       "\x48\x5d\x72\x87\x9c\xb1\xc6\xdb"
+                       "\xf0\x05\x1a\x2f\x44\x59\x6e\x83"
+                       "\x98\xad\xc2\xd7\xec\x01\x16\x2b"
+                       "\x40\x55\x6a\x7f\x94\xa9\xbe\xd3"
+                       "\xe8\xfd\x12\x27\x3c\x51\x66\x7b"
+                       "\x90\xa5\xba\xcf\xe4\xf9\x0e\x23"
+                       "\x38\x4d\x62\x77\x8c\xa1\xb6\xcb"
+                       "\xe0\xf5\x0a\x1f\x34\x49\x5e\x73"
+                       "\x88\x9d\xb2\xc7\xdc\xf1\x06\x1b"
+                       "\x30\x45\x5a\x6f\x84\x99\xae\xc3"
+                       "\xd8\xed\x02\x17\x2c\x41\x56\x6b"
+                       "\x80\x95\xaa\xbf\xd4\xe9\xfe\x13"
+                       "\x28\x3d\x52\x67\x7c\x91\xa6\xbb"
+                       "\xd0\xe5\xfa\x0f\x24\x39\x4e\x63"
+                       "\x78\x8d\xa2\xb7\xcc\xe1\xf6\x0b"
+                       "\x20\x35\x4a\x5f\x74\x89\x9e\xb3"
+                       "\xc8\xdd\xf2\x07\x1c\x31\x46\x5b"
+                       "\x70\x85\x9a\xaf\xc4\xd9\xee\x03"
+                       "\x18\x2d\x42\x57\x6c\x81\x96\xab"
+                       "\xc0\xd5\xea\xff\x14\x29\x3e\x53"
+                       "\x68\x7d\x92\xa7\xbc\xd1\xe6\xfb"
+                       "\x10\x25\x3a\x4f\x64\x79\x8e\xa3"
+                       "\xb8\xcd\xe2\xf7\x0c\x21\x36\x4b"
+                       "\x60\x75\x8a\x9f\xb4\xc9\xde\xf3"
+                       "\x08\x1d\x32\x47\x5c\x71\x86\x9b"
+                       "\xb0\xc5\xda\xef\x04\x19\x2e\x43"
+                       "\x58\x6d\x82\x97\xac\xc1\xd6\xeb"
+                       "\x00\x17\x2e\x45\x5c\x73\x8a\xa1"
+                       "\xb8\xcf\xe6\xfd\x14\x2b\x42\x59"
+                       "\x70\x87\x9e\xb5\xcc\xe3\xfa\x11"
+                       "\x28\x3f\x56\x6d\x84\x9b\xb2\xc9"
+                       "\xe0\xf7\x0e\x25\x3c\x53\x6a\x81"
+                       "\x98\xaf\xc6\xdd\xf4\x0b\x22\x39"
+                       "\x50\x67\x7e\x95\xac\xc3\xda\xf1"
+                       "\x08\x1f\x36\x4d\x64\x7b\x92\xa9"
+                       "\xc0\xd7\xee\x05\x1c\x33\x4a\x61"
+                       "\x78\x8f\xa6\xbd\xd4\xeb\x02\x19"
+                       "\x30\x47\x5e\x75\x8c\xa3\xba\xd1"
+                       "\xe8\xff\x16\x2d\x44\x5b\x72\x89"
+                       "\xa0\xb7\xce\xe5\xfc\x13\x2a\x41"
+                       "\x58\x6f\x86\x9d\xb4\xcb\xe2\xf9"
+                       "\x10\x27\x3e\x55\x6c\x83\x9a\xb1"
+                       "\xc8\xdf\xf6\x0d\x24\x3b\x52\x69"
+                       "\x80\x97\xae\xc5\xdc\xf3\x0a\x21"
+                       "\x38\x4f\x66\x7d\x94\xab\xc2\xd9"
+                       "\xf0\x07\x1e\x35\x4c\x63\x7a\x91"
+                       "\xa8\xbf\xd6\xed\x04\x1b\x32\x49"
+                       "\x60\x77\x8e\xa5\xbc\xd3\xea\x01"
+                       "\x18\x2f\x46\x5d\x74\x8b\xa2\xb9"
+                       "\xd0\xe7\xfe\x15\x2c\x43\x5a\x71"
+                       "\x88\x9f\xb6\xcd\xe4\xfb\x12\x29"
+                       "\x40\x57\x6e\x85\x9c\xb3\xca\xe1"
+                       "\xf8\x0f\x26\x3d\x54\x6b\x82\x99"
+                       "\xb0\xc7\xde\xf5\x0c\x23\x3a\x51"
+                       "\x68\x7f\x96\xad\xc4\xdb\xf2\x09"
+                       "\x20\x37\x4e\x65\x7c\x93\xaa\xc1"
+                       "\xd8\xef\x06\x1d\x34\x4b\x62\x79"
+                       "\x90\xa7\xbe\xd5\xec\x03\x1a\x31"
+                       "\x48\x5f\x76\x8d\xa4\xbb\xd2\xe9"
+                       "\x00\x19\x32\x4b\x64\x7d\x96\xaf"
+                       "\xc8\xe1\xfa\x13\x2c\x45\x5e\x77"
+                       "\x90\xa9\xc2\xdb\xf4\x0d\x26\x3f"
+                       "\x58\x71\x8a\xa3\xbc\xd5\xee\x07"
+                       "\x20\x39\x52\x6b\x84\x9d\xb6\xcf"
+                       "\xe8\x01\x1a\x33\x4c\x65\x7e\x97"
+                       "\xb0\xc9\xe2\xfb\x14\x2d\x46\x5f"
+                       "\x78\x91\xaa\xc3\xdc\xf5\x0e\x27"
+                       "\x40\x59\x72\x8b\xa4\xbd\xd6\xef"
+                       "\x08\x21\x3a\x53\x6c\x85\x9e\xb7"
+                       "\xd0\xe9\x02\x1b\x34\x4d\x66\x7f"
+                       "\x98\xb1\xca\xe3\xfc\x15\x2e\x47"
+                       "\x60\x79\x92\xab\xc4\xdd\xf6\x0f"
+                       "\x28\x41\x5a\x73\x8c\xa5\xbe\xd7"
+                       "\xf0\x09\x22\x3b\x54\x6d\x86\x9f"
+                       "\xb8\xd1\xea\x03\x1c\x35\x4e\x67"
+                       "\x80\x99\xb2\xcb\xe4\xfd\x16\x2f"
+                       "\x48\x61\x7a\x93\xac\xc5\xde\xf7"
+                       "\x10\x29\x42\x5b\x74\x8d\xa6\xbf"
+                       "\xd8\xf1\x0a\x23\x3c\x55\x6e\x87"
+                       "\xa0\xb9\xd2\xeb\x04\x1d\x36\x4f"
+                       "\x68\x81\x9a\xb3\xcc\xe5\xfe\x17"
+                       "\x30\x49\x62\x7b\x94\xad\xc6\xdf"
+                       "\xf8\x11\x2a\x43\x5c\x75\x8e\xa7"
+                       "\xc0\xd9\xf2\x0b\x24\x3d\x56\x6f"
+                       "\x88\xa1\xba\xd3\xec\x05\x1e\x37"
+                       "\x50\x69\x82\x9b\xb4\xcd\xe6\xff"
+                       "\x18\x31\x4a\x63\x7c\x95\xae\xc7"
+                       "\xe0\xf9\x12\x2b\x44\x5d\x76\x8f"
+                       "\xa8\xc1\xda\xf3\x0c\x25\x3e\x57"
+                       "\x70\x89\xa2\xbb\xd4\xed\x06\x1f"
+                       "\x38\x51\x6a\x83\x9c\xb5\xce\xe7"
+                       "\x00\x1b\x36\x51\x6c\x87\xa2\xbd"
+                       "\xd8\xf3\x0e\x29\x44\x5f\x7a\x95"
+                       "\xb0\xcb\xe6\x01\x1c\x37\x52\x6d"
+                       "\x88\xa3\xbe\xd9\xf4\x0f\x2a\x45"
+                       "\x60\x7b\x96\xb1\xcc\xe7\x02\x1d"
+                       "\x38\x53\x6e\x89\xa4\xbf\xda\xf5"
+                       "\x10\x2b\x46\x61\x7c\x97\xb2\xcd"
+                       "\xe8\x03\x1e\x39\x54\x6f\x8a\xa5"
+                       "\xc0\xdb\xf6\x11\x2c\x47\x62\x7d"
+                       "\x98\xb3\xce\xe9\x04\x1f\x3a\x55"
+                       "\x70\x8b\xa6\xc1\xdc\xf7\x12\x2d"
+                       "\x48\x63\x7e\x99\xb4\xcf\xea\x05"
+                       "\x20\x3b\x56\x71\x8c\xa7\xc2\xdd"
+                       "\xf8\x13\x2e\x49\x64\x7f\x9a\xb5"
+                       "\xd0\xeb\x06\x21\x3c\x57\x72\x8d"
+                       "\xa8\xc3\xde\xf9\x14\x2f\x4a\x65"
+                       "\x80\x9b\xb6\xd1\xec\x07\x22\x3d"
+                       "\x58\x73\x8e\xa9\xc4\xdf\xfa\x15"
+                       "\x30\x4b\x66\x81\x9c\xb7\xd2\xed"
+                       "\x08\x23\x3e\x59\x74\x8f\xaa\xc5"
+                       "\xe0\xfb\x16\x31\x4c\x67\x82\x9d"
+                       "\xb8\xd3\xee\x09\x24\x3f\x5a\x75"
+                       "\x90\xab\xc6\xe1\xfc\x17\x32\x4d"
+                       "\x68\x83\x9e\xb9\xd4\xef\x0a\x25"
+                       "\x40\x5b\x76\x91\xac\xc7\xe2\xfd"
+                       "\x18\x33\x4e\x69\x84\x9f\xba\xd5"
+                       "\xf0\x0b\x26\x41\x5c\x77\x92\xad"
+                       "\xc8\xe3\xfe\x19\x34\x4f\x6a\x85"
+                       "\xa0\xbb\xd6\xf1\x0c\x27\x42\x5d"
+                       "\x78\x93\xae\xc9\xe4\xff\x1a\x35"
+                       "\x50\x6b\x86\xa1\xbc\xd7\xf2\x0d"
+                       "\x28\x43\x5e\x79\x94\xaf\xca\xe5"
+                       "\x00\x1d\x3a\x57\x74\x91\xae\xcb"
+                       "\xe8\x05\x22\x3f\x5c\x79\x96\xb3"
+                       "\xd0\xed\x0a\x27\x44\x61\x7e\x9b"
+                       "\xb8\xd5\xf2\x0f\x2c\x49\x66\x83"
+                       "\xa0\xbd\xda\xf7\x14\x31\x4e\x6b"
+                       "\x88\xa5\xc2\xdf\xfc\x19\x36\x53"
+                       "\x70\x8d\xaa\xc7\xe4\x01\x1e\x3b"
+                       "\x58\x75\x92\xaf\xcc\xe9\x06\x23"
+                       "\x40\x5d\x7a\x97\xb4\xd1\xee\x0b"
+                       "\x28\x45\x62\x7f\x9c\xb9\xd6\xf3"
+                       "\x10\x2d\x4a\x67\x84\xa1\xbe\xdb"
+                       "\xf8\x15\x32\x4f\x6c\x89\xa6\xc3"
+                       "\xe0\xfd\x1a\x37\x54\x71\x8e\xab"
+                       "\xc8\xe5\x02\x1f\x3c\x59\x76\x93"
+                       "\xb0\xcd\xea\x07\x24\x41\x5e\x7b"
+                       "\x98\xb5\xd2\xef\x0c\x29\x46\x63"
+                       "\x80\x9d\xba\xd7\xf4\x11\x2e\x4b"
+                       "\x68\x85\xa2\xbf\xdc\xf9\x16\x33"
+                       "\x50\x6d\x8a\xa7\xc4\xe1\xfe\x1b"
+                       "\x38\x55\x72\x8f\xac\xc9\xe6\x03"
+                       "\x20\x3d\x5a\x77\x94\xb1\xce\xeb"
+                       "\x08\x25\x42\x5f\x7c\x99\xb6\xd3"
+                       "\xf0\x0d\x2a\x47\x64\x81\x9e\xbb"
+                       "\xd8\xf5\x12\x2f\x4c\x69\x86\xa3"
+                       "\xc0\xdd\xfa\x17\x34\x51\x6e\x8b"
+                       "\xa8\xc5\xe2\xff\x1c\x39\x56\x73"
+                       "\x90\xad\xca\xe7\x04\x21\x3e\x5b"
+                       "\x78\x95\xb2\xcf\xec\x09\x26\x43"
+                       "\x60\x7d\x9a\xb7\xd4\xf1\x0e\x2b"
+                       "\x48\x65\x82\x9f\xbc\xd9\xf6\x13"
+                       "\x30\x4d\x6a\x87\xa4\xc1\xde\xfb"
+                       "\x18\x35\x52\x6f\x8c\xa9\xc6\xe3"
+                       "\x00\x1f\x3e\x5d\x7c\x9b\xba\xd9"
+                       "\xf8\x17\x36\x55\x74\x93\xb2\xd1"
+                       "\xf0\x0f\x2e\x4d\x6c\x8b\xaa\xc9"
+                       "\xe8\x07\x26\x45\x64\x83\xa2\xc1"
+                       "\xe0\xff\x1e\x3d\x5c\x7b\x9a\xb9"
+                       "\xd8\xf7\x16\x35\x54\x73\x92\xb1"
+                       "\xd0\xef\x0e\x2d\x4c\x6b\x8a\xa9"
+                       "\xc8\xe7\x06\x25\x44\x63\x82\xa1"
+                       "\xc0\xdf\xfe\x1d\x3c\x5b\x7a\x99"
+                       "\xb8\xd7\xf6\x15\x34\x53\x72\x91"
+                       "\xb0\xcf\xee\x0d\x2c\x4b\x6a\x89"
+                       "\xa8\xc7\xe6\x05\x24\x43\x62\x81"
+                       "\xa0\xbf\xde\xfd\x1c\x3b\x5a\x79"
+                       "\x98\xb7\xd6\xf5\x14\x33\x52\x71"
+                       "\x90\xaf\xce\xed\x0c\x2b\x4a\x69"
+                       "\x88\xa7\xc6\xe5\x04\x23\x42\x61"
+                       "\x80\x9f\xbe\xdd\xfc\x1b\x3a\x59"
+                       "\x78\x97\xb6\xd5\xf4\x13\x32\x51"
+                       "\x70\x8f\xae\xcd\xec\x0b\x2a\x49"
+                       "\x68\x87\xa6\xc5\xe4\x03\x22\x41"
+                       "\x60\x7f\x9e\xbd\xdc\xfb\x1a\x39"
+                       "\x58\x77\x96\xb5\xd4\xf3\x12\x31"
+                       "\x50\x6f\x8e\xad\xcc\xeb\x0a\x29"
+                       "\x48\x67\x86\xa5\xc4\xe3\x02\x21"
+                       "\x40\x5f\x7e\x9d\xbc\xdb\xfa\x19"
+                       "\x38\x57\x76\x95\xb4\xd3\xf2\x11"
+                       "\x30\x4f\x6e\x8d\xac\xcb\xea\x09"
+                       "\x28\x47\x66\x85\xa4\xc3\xe2\x01"
+                       "\x20\x3f\x5e\x7d\x9c\xbb\xda\xf9"
+                       "\x18\x37\x56\x75\x94\xb3\xd2\xf1"
+                       "\x10\x2f\x4e\x6d\x8c\xab\xca\xe9"
+                       "\x08\x27\x46\x65\x84\xa3\xc2\xe1"
+                       "\x00\x21\x42\x63",
+               .ilen = 4100,
+               .result =
+                       "\xf0\x5c\x74\xad\x4e\xbc\x99\xe2"
+                       "\xae\xff\x91\x3a\x44\xcf\x38\x32"
+                       "\x1e\xad\xa7\xcd\xa1\x39\x95\xaa"
+                       "\x10\xb1\xb3\x2e\x04\x31\x8f\x86"
+                       "\xf2\x62\x74\x70\x0c\xa4\x46\x08"
+                       "\xa8\xb7\x99\xa8\xe9\xd2\x73\x79"
+                       "\x7e\x6e\xd4\x8f\x1e\xc7\x8e\x31"
+                       "\x0b\xfa\x4b\xce\xfd\xf3\x57\x71"
+                       "\xe9\x46\x03\xa5\x3d\x34\x00\xe2"
+                       "\x18\xff\x75\x6d\x06\x2d\x00\xab"
+                       "\xb9\x3e\x6c\x59\xc5\x84\x06\xb5"
+                       "\x8b\xd0\x89\x9c\x4a\x79\x16\xc6"
+                       "\x3d\x74\x54\xfa\x44\xcd\x23\x26"
+                       "\x5c\xcf\x7e\x28\x92\x32\xbf\xdf"
+                       "\xa7\x20\x3c\x74\x58\x2a\x9a\xde"
+                       "\x61\x00\x1c\x4f\xff\x59\xc4\x22"
+                       "\xac\x3c\xd0\xe8\x6c\xf9\x97\x1b"
+                       "\x58\x9b\xad\x71\xe8\xa9\xb5\x0d"
+                       "\xee\x2f\x04\x1f\x7f\xbc\x99\xee"
+                       "\x84\xff\x42\x60\xdc\x3a\x18\xa5"
+                       "\x81\xf9\xef\xdc\x7a\x0f\x65\x41"
+                       "\x2f\xa3\xd3\xf9\xc2\xcb\xc0\x4d"
+                       "\x8f\xd3\x76\x96\xad\x49\x6d\x38"
+                       "\x3d\x39\x0b\x6c\x80\xb7\x54\x69"
+                       "\xf0\x2c\x90\x02\x29\x0d\x1c\x12"
+                       "\xad\x55\xc3\x8b\x68\xd9\xcc\xb3"
+                       "\xb2\x64\x33\x90\x5e\xca\x4b\xe2"
+                       "\xfb\x75\xdc\x63\xf7\x9f\x82\x74"
+                       "\xf0\xc9\xaa\x7f\xe9\x2a\x9b\x33"
+                       "\xbc\x88\x00\x7f\xca\xb2\x1f\x14"
+                       "\xdb\xc5\x8e\x7b\x11\x3c\x3e\x08"
+                       "\xf3\x83\xe8\xe0\x94\x86\x2e\x92"
+                       "\x78\x6b\x01\xc9\xc7\x83\xba\x21"
+                       "\x6a\x25\x15\x33\x4e\x45\x08\xec"
+                       "\x35\xdb\xe0\x6e\x31\x51\x79\xa9"
+                       "\x42\x44\x65\xc1\xa0\xf1\xf9\x2a"
+                       "\x70\xd5\xb6\xc6\xc1\x8c\x39\xfc"
+                       "\x25\xa6\x55\xd9\xdd\x2d\x4c\xec"
+                       "\x49\xc6\xeb\x0e\xa8\x25\x2a\x16"
+                       "\x1b\x66\x84\xda\xe2\x92\xe5\xc0"
+                       "\xc8\x53\x07\xaf\x80\x84\xec\xfd"
+                       "\xcd\xd1\x6e\xcd\x6f\x6a\xf5\x36"
+                       "\xc5\x15\xe5\x25\x7d\x77\xd1\x1a"
+                       "\x93\x36\xa9\xcf\x7c\xa4\x54\x4a"
+                       "\x06\x51\x48\x4e\xf6\x59\x87\xd2"
+                       "\x04\x02\xef\xd3\x44\xde\x76\x31"
+                       "\xb3\x34\x17\x1b\x9d\x66\x11\x9f"
+                       "\x1e\xcc\x17\xe9\xc7\x3c\x1b\xe7"
+                       "\xcb\x50\x08\xfc\xdc\x2b\x24\xdb"
+                       "\x65\x83\xd0\x3b\xe3\x30\xea\x94"
+                       "\x6c\xe7\xe8\x35\x32\xc7\xdb\x64"
+                       "\xb4\x01\xab\x36\x2c\x77\x13\xaf"
+                       "\xf8\x2b\x88\x3f\x54\x39\xc4\x44"
+                       "\xfe\xef\x6f\x68\x34\xbe\x0f\x05"
+                       "\x16\x6d\xf6\x0a\x30\xe7\xe3\xed"
+                       "\xc4\xde\x3c\x1b\x13\xd8\xdb\xfe"
+                       "\x41\x62\xe5\x28\xd4\x8d\xa3\xc7"
+                       "\x93\x97\xc6\x48\x45\x1d\x9f\x83"
+                       "\xdf\x4b\x40\x3e\x42\x25\x87\x80"
+                       "\x4c\x7d\xa8\xd4\x98\x23\x95\x75"
+                       "\x41\x8c\xda\x41\x9b\xd4\xa7\x06"
+                       "\xb5\xf1\x71\x09\x53\xbe\xca\xbf"
+                       "\x32\x03\xed\xf0\x50\x1c\x56\x39"
+                       "\x5b\xa4\x75\x18\xf7\x9b\x58\xef"
+                       "\x53\xfc\x2a\x38\x23\x15\x75\xcd"
+                       "\x45\xe5\x5a\x82\x55\xba\x21\xfa"
+                       "\xd4\xbd\xc6\x94\x7c\xc5\x80\x12"
+                       "\xf7\x4b\x32\xc4\x9a\x82\xd8\x28"
+                       "\x8f\xd9\xc2\x0f\x60\x03\xbe\x5e"
+                       "\x21\xd6\x5f\x58\xbf\x5c\xb1\x32"
+                       "\x82\x8d\xa9\xe5\xf2\x66\x1a\xc0"
+                       "\xa0\xbc\x58\x2f\x71\xf5\x2f\xed"
+                       "\xd1\x26\xb9\xd8\x49\x5a\x07\x19"
+                       "\x01\x7c\x59\xb0\xf8\xa4\xb7\xd3"
+                       "\x7b\x1a\x8c\x38\xf4\x50\xa4\x59"
+                       "\xb0\xcc\x41\x0b\x88\x7f\xe5\x31"
+                       "\xb3\x42\xba\xa2\x7e\xd4\x32\x71"
+                       "\x45\x87\x48\xa9\xc2\xf2\x89\xb3"
+                       "\xe4\xa7\x7e\x52\x15\x61\xfa\xfe"
+                       "\xc9\xdd\x81\xeb\x13\xab\xab\xc3"
+                       "\x98\x59\xd8\x16\x3d\x14\x7a\x1c"
+                       "\x3c\x41\x9a\x16\x16\x9b\xd2\xd2"
+                       "\x69\x3a\x29\x23\xac\x86\x32\xa5"
+                       "\x48\x9c\x9e\xf3\x47\x77\x81\x70"
+                       "\x24\xe8\x85\xd2\xf5\xb5\xfa\xff"
+                       "\x59\x6a\xd3\x50\x59\x43\x59\xde"
+                       "\xd9\xf1\x55\xa5\x0c\xc3\x1a\x1a"
+                       "\x18\x34\x0d\x1a\x63\x33\xed\x10"
+                       "\xe0\x1d\x2a\x18\xd2\xc0\x54\xa8"
+                       "\xca\xb5\x9a\xd3\xdd\xca\x45\x84"
+                       "\x50\xe7\x0f\xfe\xa4\x99\x5a\xbe"
+                       "\x43\x2d\x9a\xcb\x92\x3f\x5a\x1d"
+                       "\x85\xd8\xc9\xdf\x68\xc9\x12\x80"
+                       "\x56\x0c\xdc\x00\xdc\x3a\x7d\x9d"
+                       "\xa3\xa2\xe8\x4d\xbf\xf9\x70\xa0"
+                       "\xa4\x13\x4f\x6b\xaf\x0a\x89\x7f"
+                       "\xda\xf0\xbf\x9b\xc8\x1d\xe5\xf8"
+                       "\x2e\x8b\x07\xb5\x73\x1b\xcc\xa2"
+                       "\xa6\xad\x30\xbc\x78\x3c\x5b\x10"
+                       "\xfa\x5e\x62\x2d\x9e\x64\xb3\x33"
+                       "\xce\xf9\x1f\x86\xe7\x8b\xa2\xb8"
+                       "\xe8\x99\x57\x8c\x11\xed\x66\xd9"
+                       "\x3c\x72\xb9\xc3\xe6\x4e\x17\x3a"
+                       "\x6a\xcb\x42\x24\x06\xed\x3e\x4e"
+                       "\xa3\xe8\x6a\x94\xda\x0d\x4e\xd5"
+                       "\x14\x19\xcf\xb6\x26\xd8\x2e\xcc"
+                       "\x64\x76\x38\x49\x4d\xfe\x30\x6d"
+                       "\xe4\xc8\x8c\x7b\xc4\xe0\x35\xba"
+                       "\x22\x6e\x76\xe1\x1a\xf2\x53\xc3"
+                       "\x28\xa2\x82\x1f\x61\x69\xad\xc1"
+                       "\x7b\x28\x4b\x1e\x6c\x85\x95\x9b"
+                       "\x51\xb5\x17\x7f\x12\x69\x8c\x24"
+                       "\xd5\xc7\x5a\x5a\x11\x54\xff\x5a"
+                       "\xf7\x16\xc3\x91\xa6\xf0\xdc\x0a"
+                       "\xb6\xa7\x4a\x0d\x7a\x58\xfe\xa5"
+                       "\xf5\xcb\x8f\x7b\x0e\xea\x57\xe7"
+                       "\xbd\x79\xd6\x1c\x88\x23\x6c\xf2"
+                       "\x4d\x29\x77\x53\x35\x6a\x00\x8d"
+                       "\xcd\xa3\x58\xbe\x77\x99\x18\xf8"
+                       "\xe6\xe1\x8f\xe9\x37\x8f\xe3\xe2"
+                       "\x5a\x8a\x93\x25\xaf\xf3\x78\x80"
+                       "\xbe\xa6\x1b\xc6\xac\x8b\x1c\x91"
+                       "\x58\xe1\x9f\x89\x35\x9d\x1d\x21"
+                       "\x29\x9f\xf4\x99\x02\x27\x0f\xa8"
+                       "\x4f\x79\x94\x2b\x33\x2c\xda\xa2"
+                       "\x26\x39\x83\x94\xef\x27\xd8\x53"
+                       "\x8f\x66\x0d\xe4\x41\x7d\x34\xcd"
+                       "\x43\x7c\x95\x0a\x53\xef\x66\xda"
+                       "\x7e\x9b\xf3\x93\xaf\xd0\x73\x71"
+                       "\xba\x40\x9b\x74\xf8\xd7\xd7\x41"
+                       "\x6d\xaf\x72\x9c\x8d\x21\x87\x3c"
+                       "\xfd\x0a\x90\xa9\x47\x96\x9e\xd3"
+                       "\x88\xee\x73\xcf\x66\x2f\x52\x56"
+                       "\x6d\xa9\x80\x4c\xe2\x6f\x62\x88"
+                       "\x3f\x0e\x54\x17\x48\x80\x5d\xd3"
+                       "\xc3\xda\x25\x3d\xa1\xc8\xcb\x9f"
+                       "\x9b\x70\xb3\xa1\xeb\x04\x52\xa1"
+                       "\xf2\x22\x0f\xfc\xc8\x18\xfa\xf9"
+                       "\x85\x9c\xf1\xac\xeb\x0c\x02\x46"
+                       "\x75\xd2\xf5\x2c\xe3\xd2\x59\x94"
+                       "\x12\xf3\x3c\xfc\xd7\x92\xfa\x36"
+                       "\xba\x61\x34\x38\x7c\xda\x48\x3e"
+                       "\x08\xc9\x39\x23\x5e\x02\x2c\x1a"
+                       "\x18\x7e\xb4\xd9\xfd\x9e\x40\x02"
+                       "\xb1\x33\x37\x32\xe7\xde\xd6\xd0"
+                       "\x7c\x58\x65\x4b\xf8\x34\x27\x9c"
+                       "\x44\xb4\xbd\xe9\xe9\x4c\x78\x7d"
+                       "\x4b\x9f\xce\xb1\xcd\x47\xa5\x37"
+                       "\xe5\x6d\xbd\xb9\x43\x94\x0a\xd4"
+                       "\xd6\xf9\x04\x5f\xb5\x66\x6c\x1a"
+                       "\x35\x12\xe3\x36\x28\x27\x36\x58"
+                       "\x01\x2b\x79\xe4\xba\x6d\x10\x7d"
+                       "\x65\xdf\x84\x95\xf4\xd5\xb6\x8f"
+                       "\x2b\x9f\x96\x00\x86\x60\xf0\x21"
+                       "\x76\xa8\x6a\x8c\x28\x1c\xb3\x6b"
+                       "\x97\xd7\xb6\x53\x2a\xcc\xab\x40"
+                       "\x9d\x62\x79\x58\x52\xe6\x65\xb7"
+                       "\xab\x55\x67\x9c\x89\x7c\x03\xb0"
+                       "\x73\x59\xc5\x81\xf5\x18\x17\x5c"
+                       "\x89\xf3\x78\x35\x44\x62\x78\x72"
+                       "\xd0\x96\xeb\x31\xe7\x87\x77\x14"
+                       "\x99\x51\xf2\x59\x26\x9e\xb5\xa6"
+                       "\x45\xfe\x6e\xbd\x07\x4c\x94\x5a"
+                       "\xa5\x7d\xfc\xf1\x2b\x77\xe2\xfe"
+                       "\x17\xd4\x84\xa0\xac\xb5\xc7\xda"
+                       "\xa9\x1a\xb6\xf3\x74\x11\xb4\x9d"
+                       "\xfb\x79\x2e\x04\x2d\x50\x28\x83"
+                       "\xbf\xc6\x52\xd3\x34\xd6\xe8\x7a"
+                       "\xb6\xea\xe7\xa8\x6c\x15\x1e\x2c"
+                       "\x57\xbc\x48\x4e\x5f\x5c\xb6\x92"
+                       "\xd2\x49\x77\x81\x6d\x90\x70\xae"
+                       "\x98\xa1\x03\x0d\x6b\xb9\x77\x14"
+                       "\xf1\x4e\x23\xd3\xf8\x68\xbd\xc2"
+                       "\xfe\x04\xb7\x5c\xc5\x17\x60\x8f"
+                       "\x65\x54\xa4\x7a\x42\xdc\x18\x0d"
+                       "\xb5\xcf\x0f\xd3\xc7\x91\x66\x1b"
+                       "\x45\x42\x27\x75\x50\xe5\xee\xb8"
+                       "\x7f\x33\x2c\xba\x4a\x92\x4d\x2c"
+                       "\x3c\xe3\x0d\x80\x01\xba\x0d\x29"
+                       "\xd8\x3c\xe9\x13\x16\x57\xe6\xea"
+                       "\x94\x52\xe7\x00\x4d\x30\xb0\x0f"
+                       "\x35\xb8\xb8\xa7\xb1\xb5\x3b\x44"
+                       "\xe1\x2f\xfd\x88\xed\x43\xe7\x52"
+                       "\x10\x93\xb3\x8a\x30\x6b\x0a\xf7"
+                       "\x23\xc6\x50\x9d\x4a\xb0\xde\xc3"
+                       "\xdc\x9b\x2f\x01\x56\x36\x09\xc5"
+                       "\x2f\x6b\xfe\xf1\xd8\x27\x45\x03"
+                       "\x30\x5e\x5c\x5b\xb4\x62\x0e\x1a"
+                       "\xa9\x21\x2b\x92\x94\x87\x62\x57"
+                       "\x4c\x10\x74\x1a\xf1\x0a\xc5\x84"
+                       "\x3b\x9e\x72\x02\xd7\xcc\x09\x56"
+                       "\xbd\x54\xc1\xf0\xc3\xe3\xb3\xf8"
+                       "\xd2\x0d\x61\xcb\xef\xce\x0d\x05"
+                       "\xb0\x98\xd9\x8e\x4f\xf9\xbc\x93"
+                       "\xa6\xea\xc8\xcf\x10\x53\x4b\xf1"
+                       "\xec\xfc\x89\xf9\x64\xb0\x22\xbf"
+                       "\x9e\x55\x46\x9f\x7c\x50\x8e\x84"
+                       "\x54\x20\x98\xd7\x6c\x40\x1e\xdb"
+                       "\x69\x34\x78\x61\x24\x21\x9c\x8a"
+                       "\xb3\x62\x31\x8b\x6e\xf5\x2a\x35"
+                       "\x86\x13\xb1\x6c\x64\x2e\x41\xa5"
+                       "\x05\xf2\x42\xba\xd2\x3a\x0d\x8e"
+                       "\x8a\x59\x94\x3c\xcf\x36\x27\x82"
+                       "\xc2\x45\xee\x58\xcd\x88\xb4\xec"
+                       "\xde\xb2\x96\x0a\xaf\x38\x6f\x88"
+                       "\xd7\xd8\xe1\xdf\xb9\x96\xa9\x0a"
+                       "\xb1\x95\x28\x86\x20\xe9\x17\x49"
+                       "\xa2\x29\x38\xaa\xa5\xe9\x6e\xf1"
+                       "\x19\x27\xc0\xd5\x2a\x22\xc3\x0b"
+                       "\xdb\x7c\x73\x10\xb9\xba\x89\x76"
+                       "\x54\xae\x7d\x71\xb3\x93\xf6\x32"
+                       "\xe6\x47\x43\x55\xac\xa0\x0d\xc2"
+                       "\x93\x27\x4a\x8e\x0e\x74\x15\xc7"
+                       "\x0b\x85\xd9\x0c\xa9\x30\x7a\x3e"
+                       "\xea\x8f\x85\x6d\x3a\x12\x4f\x72"
+                       "\x69\x58\x7a\x80\xbb\xb5\x97\xf3"
+                       "\xcf\x70\xd2\x5d\xdd\x4d\x21\x79"
+                       "\x54\x4d\xe4\x05\xe8\xbd\xc2\x62"
+                       "\xb1\x3b\x77\x1c\xd6\x5c\xf3\xa0"
+                       "\x79\x00\xa8\x6c\x29\xd9\x18\x24"
+                       "\x36\xa2\x46\xc0\x96\x65\x7f\xbd"
+                       "\x2a\xed\x36\x16\x0c\xaa\x9f\xf4"
+                       "\xc5\xb4\xe2\x12\xed\x69\xed\x4f"
+                       "\x26\x2c\x39\x52\x89\x98\xe7\x2c"
+                       "\x99\xa4\x9e\xa3\x9b\x99\x46\x7a"
+                       "\x3a\xdc\xa8\x59\xa3\xdb\xc3\x3b"
+                       "\x95\x0d\x3b\x09\x6e\xee\x83\x5d"
+                       "\x32\x4d\xed\xab\xfa\x98\x14\x4e"
+                       "\xc3\x15\x45\x53\x61\xc4\x93\xbd"
+                       "\x90\xf4\x99\x95\x4c\xe6\x76\x92"
+                       "\x29\x90\x46\x30\x92\x69\x7d\x13"
+                       "\xf2\xa5\xcd\x69\x49\x44\xb2\x0f"
+                       "\x63\x40\x36\x5f\x09\xe2\x78\xf8"
+                       "\x91\xe3\xe2\xfa\x10\xf7\xc8\x24"
+                       "\xa8\x89\x32\x5c\x37\x25\x1d\xb2"
+                       "\xea\x17\x8a\x0a\xa9\x64\xc3\x7c"
+                       "\x3c\x7c\xbd\xc6\x79\x34\xe7\xe2"
+                       "\x85\x8e\xbf\xf8\xde\x92\xa0\xae"
+                       "\x20\xc4\xf6\xbb\x1f\x38\x19\x0e"
+                       "\xe8\x79\x9c\xa1\x23\xe9\x54\x7e"
+                       "\x37\x2f\xe2\x94\x32\xaf\xa0\x23"
+                       "\x49\xe4\xc0\xb3\xac\x00\x8f\x36"
+                       "\x05\xc4\xa6\x96\xec\x05\x98\x4f"
+                       "\x96\x67\x57\x1f\x20\x86\x1b\x2d"
+                       "\x69\xe4\x29\x93\x66\x5f\xaf\x6b"
+                       "\x88\x26\x2c\x67\x02\x4b\x52\xd0"
+                       "\x83\x7a\x43\x1f\xc0\x71\x15\x25"
+                       "\x77\x65\x08\x60\x11\x76\x4c\x8d"
+                       "\xed\xa9\x27\xc6\xb1\x2a\x2c\x6a"
+                       "\x4a\x97\xf5\xc6\xb7\x70\x42\xd3"
+                       "\x03\xd1\x24\x95\xec\x6d\xab\x38"
+                       "\x72\xce\xe2\x8b\x33\xd7\x51\x09"
+                       "\xdc\x45\xe0\x09\x96\x32\xf3\xc4"
+                       "\x84\xdc\x73\x73\x2d\x1b\x11\x98"
+                       "\xc5\x0e\x69\x28\x94\xc7\xb5\x4d"
+                       "\xc8\x8a\xd0\xaa\x13\x2e\x18\x74"
+                       "\xdd\xd1\x1e\xf3\x90\xe8\xfc\x9a"
+                       "\x72\x4a\x0e\xd1\xe4\xfb\x0d\x96"
+                       "\xd1\x0c\x79\x85\x1b\x1c\xfe\xe1"
+                       "\x62\x8f\x7a\x73\x32\xab\xc8\x18"
+                       "\x69\xe3\x34\x30\xdf\x13\xa6\xe5"
+                       "\xe8\x0e\x67\x7f\x81\x11\xb4\x60"
+                       "\xc7\xbd\x79\x65\x50\xdc\xc4\x5b"
+                       "\xde\x39\xa4\x01\x72\x63\xf3\xd1"
+                       "\x64\x4e\xdf\xfc\x27\x92\x37\x0d"
+                       "\x57\xcd\x11\x4f\x11\x04\x8e\x1d"
+                       "\x16\xf7\xcd\x92\x9a\x99\x30\x14"
+                       "\xf1\x7c\x67\x1b\x1f\x41\x0b\xe8"
+                       "\x32\xe8\xb8\xc1\x4f\x54\x86\x4f"
+                       "\xe5\x79\x81\x73\xcd\x43\x59\x68"
+                       "\x73\x02\x3b\x78\x21\x72\x43\x00"
+                       "\x49\x17\xf7\x00\xaf\x68\x24\x53"
+                       "\x05\x0a\xc3\x33\xe0\x33\x3f\x69"
+                       "\xd2\x84\x2f\x0b\xed\xde\x04\xf4"
+                       "\x11\x94\x13\x69\x51\x09\x28\xde"
+                       "\x57\x5c\xef\xdc\x9a\x49\x1c\x17"
+                       "\x97\xf3\x96\xc1\x7f\x5d\x2e\x7d"
+                       "\x55\xb8\xb3\x02\x09\xb3\x1f\xe7"
+                       "\xc9\x8d\xa3\x36\x34\x8a\x77\x13"
+                       "\x30\x63\x4c\xa5\xcd\xc3\xe0\x7e"
+                       "\x05\xa1\x7b\x0c\xcb\x74\x47\x31"
+                       "\x62\x03\x43\xf1\x87\xb4\xb0\x85"
+                       "\x87\x8e\x4b\x25\xc7\xcf\xae\x4b"
+                       "\x36\x46\x3e\x62\xbc\x6f\xeb\x5f"
+                       "\x73\xac\xe6\x07\xee\xc1\xa1\xd6"
+                       "\xc4\xab\xc9\xd6\x89\x45\xe1\xf1"
+                       "\x04\x4e\x1a\x6f\xbb\x4f\x3a\xa3"
+                       "\xa0\xcb\xa3\x0a\xd8\x71\x35\x55"
+                       "\xe4\xbc\x2e\x04\x06\xe6\xff\x5b"
+                       "\x1c\xc0\x11\x7c\xc5\x17\xf3\x38"
+                       "\xcf\xe9\xba\x0f\x0e\xef\x02\xc2"
+                       "\x8d\xc6\xbc\x4b\x67\x20\x95\xd7"
+                       "\x2c\x45\x5b\x86\x44\x8c\x6f\x2e"
+                       "\x7e\x9f\x1c\x77\xba\x6b\x0e\xa3"
+                       "\x69\xdc\xab\x24\x57\x60\x47\xc1"
+                       "\xd1\xa5\x9d\x23\xe6\xb1\x37\xfe"
+                       "\x93\xd2\x4c\x46\xf9\x0c\xc6\xfb"
+                       "\xd6\x9d\x99\x69\xab\x7a\x07\x0c"
+                       "\x65\xe7\xc4\x08\x96\xe2\xa5\x01"
+                       "\x3f\x46\x07\x05\x7e\xe8\x9a\x90"
+                       "\x50\xdc\xe9\x7a\xea\xa1\x39\x6e"
+                       "\x66\xe4\x6f\xa5\x5f\xb2\xd9\x5b"
+                       "\xf5\xdb\x2a\x32\xf0\x11\x6f\x7c"
+                       "\x26\x10\x8f\x3d\x80\xe9\x58\xf7"
+                       "\xe0\xa8\x57\xf8\xdb\x0e\xce\x99"
+                       "\x63\x19\x3d\xd5\xec\x1b\x77\x69"
+                       "\x98\xf6\xe4\x5f\x67\x17\x4b\x09"
+                       "\x85\x62\x82\x70\x18\xe2\x9a\x78"
+                       "\xe2\x62\xbd\xb4\xf1\x42\xc6\xfb"
+                       "\x08\xd0\xbd\xeb\x4e\x09\xf2\xc8"
+                       "\x1e\xdc\x3d\x32\x21\x56\x9c\x4f"
+                       "\x35\xf3\x61\x06\x72\x84\xc4\x32"
+                       "\xf2\xf1\xfa\x0b\x2f\xc3\xdb\x02"
+                       "\x04\xc2\xde\x57\x64\x60\x8d\xcf"
+                       "\xcb\x86\x5d\x97\x3e\xb1\x9c\x01"
+                       "\xd6\x28\x8f\x99\xbc\x46\xeb\x05"
+                       "\xaf\x7e\xb8\x21\x2a\x56\x85\x1c"
+                       "\xb3\x71\xa0\xde\xca\x96\xf1\x78"
+                       "\x49\xa2\x99\x81\x80\x5c\x01\xf5"
+                       "\xa0\xa2\x56\x63\xe2\x70\x07\xa5"
+                       "\x95\xd6\x85\xeb\x36\x9e\xa9\x51"
+                       "\x66\x56\x5f\x1d\x02\x19\xe2\xf6"
+                       "\x4f\x73\x38\x09\x75\x64\x48\xe0"
+                       "\xf1\x7e\x0e\xe8\x9d\xf9\xed\x94"
+                       "\xfe\x16\x26\x62\x49\x74\xf4\xb0"
+                       "\xd4\xa9\x6c\xb0\xfd\x53\xe9\x81"
+                       "\xe0\x7a\xbf\xcf\xb5\xc4\x01\x81"
+                       "\x79\x99\x77\x01\x3b\xe9\xa2\xb6"
+                       "\xe6\x6a\x8a\x9e\x56\x1c\x8d\x1e"
+                       "\x8f\x06\x55\x2c\x6c\xdc\x92\x87"
+                       "\x64\x3b\x4b\x19\xa1\x13\x64\x1d"
+                       "\x4a\xe9\xc0\x00\xb8\x95\xef\x6b"
+                       "\x1a\x86\x6d\x37\x52\x02\xc2\xe0"
+                       "\xc8\xbb\x42\x0c\x02\x21\x4a\xc9"
+                       "\xef\xa0\x54\xe4\x5e\x16\x53\x81"
+                       "\x70\x62\x10\xaf\xde\xb8\xb5\xd3"
+                       "\xe8\x5e\x6c\xc3\x8a\x3e\x18\x07"
+                       "\xf2\x2f\x7d\xa7\xe1\x3d\x4e\xb4"
+                       "\x26\xa7\xa3\x93\x86\xb2\x04\x1e"
+                       "\x53\x5d\x86\xd6\xde\x65\xca\xe3"
+                       "\x4e\xc1\xcf\xef\xc8\x70\x1b\x83"
+                       "\x13\xdd\x18\x8b\x0d\x76\xd2\xf6"
+                       "\x37\x7a\x93\x7a\x50\x11\x9f\x96"
+                       "\x86\x25\xfd\xac\xdc\xbe\x18\x93"
+                       "\x19\x6b\xec\x58\x4f\xb9\x75\xa7"
+                       "\xdd\x3f\x2f\xec\xc8\x5a\x84\xab"
+                       "\xd5\xe4\x8a\x07\xf6\x4d\x23\xd6"
+                       "\x03\xfb\x03\x6a\xea\x66\xbf\xd4"
+                       "\xb1\x34\xfb\x78\xe9\x55\xdc\x7c"
+                       "\x3d\x9c\xe5\x9a\xac\xc3\x7a\x80"
+                       "\x24\x6d\xa0\xef\x25\x7c\xb7\xea"
+                       "\xce\x4d\x5f\x18\x60\xce\x87\x22"
+                       "\x66\x2f\xd5\xdd\xdd\x02\x21\x75"
+                       "\x82\xa0\x1f\x58\xc6\xd3\x62\xf7"
+                       "\x32\xd8\xaf\x1e\x07\x77\x51\x96"
+                       "\xd5\x6b\x1e\x7e\x80\x02\xe8\x67"
+                       "\xea\x17\x0b\x10\xd2\x3f\x28\x25"
+                       "\x4f\x05\x77\x02\x14\x69\xf0\x2c"
+                       "\xbe\x0c\xf1\x74\x30\xd1\xb9\x9b"
+                       "\xfc\x8c\xbb\x04\x16\xd9\xba\xc3"
+                       "\xbc\x91\x8a\xc4\x30\xa4\xb0\x12"
+                       "\x4c\x21\x87\xcb\xc9\x1d\x16\x96"
+                       "\x07\x6f\x23\x54\xb9\x6f\x79\xe5"
+                       "\x64\xc0\x64\xda\xb1\xae\xdd\x60"
+                       "\x6c\x1a\x9d\xd3\x04\x8e\x45\xb0"
+                       "\x92\x61\xd0\x48\x81\xed\x5e\x1d"
+                       "\xa0\xc9\xa4\x33\xc7\x13\x51\x5d"
+                       "\x7f\x83\x73\xb6\x70\x18\x65\x3e"
+                       "\x2f\x0e\x7a\x12\x39\x98\xab\xd8"
+                       "\x7e\x6f\xa3\xd1\xba\x56\xad\xbd"
+                       "\xf0\x03\x01\x1c\x85\x35\x9f\xeb"
+                       "\x19\x63\xa1\xaf\xfe\x2d\x35\x50"
+                       "\x39\xa0\x65\x7c\x95\x7e\x6b\xfe"
+                       "\xc1\xac\x07\x7c\x98\x4f\xbe\x57"
+                       "\xa7\x22\xec\xe2\x7e\x29\x09\x53"
+                       "\xe8\xbf\xb4\x7e\x3f\x8f\xfc\x14"
+                       "\xce\x54\xf9\x18\x58\xb5\xff\x44"
+                       "\x05\x9d\xce\x1b\xb6\x82\x23\xc8"
+                       "\x2e\xbc\x69\xbb\x4a\x29\x0f\x65"
+                       "\x94\xf0\x63\x06\x0e\xef\x8c\xbd"
+                       "\xff\xfd\xb0\x21\x6e\x57\x05\x75"
+                       "\xda\xd5\xc4\xeb\x8d\x32\xf7\x50"
+                       "\xd3\x6f\x22\xed\x5f\x8e\xa2\x5b"
+                       "\x80\x8c\xc8\x78\x40\x24\x4b\x89"
+                       "\x30\xce\x7a\x97\x0e\xc4\xaf\xef"
+                       "\x9b\xb4\xcd\x66\x74\x14\x04\x2b"
+                       "\xf7\xce\x0b\x1c\x6e\xc2\x78\x8c"
+                       "\xca\xc5\xd0\x1c\x95\x4a\x91\x2d"
+                       "\xa7\x20\xeb\x86\x52\xb7\x67\xd8"
+                       "\x0c\xd6\x04\x14\xde\x51\x74\x75"
+                       "\xe7\x11\xb4\x87\xa3\x3d\x2d\xad"
+                       "\x4f\xef\xa0\x0f\x70\x00\x6d\x13"
+                       "\x19\x1d\x41\x50\xe9\xd8\xf0\x32"
+                       "\x71\xbc\xd3\x11\xf2\xac\xbe\xaf"
+                       "\x75\x46\x65\x4e\x07\x34\x37\xa3"
+                       "\x89\xfe\x75\xd4\x70\x4c\xc6\x3f"
+                       "\x69\x24\x0e\x38\x67\x43\x8c\xde"
+                       "\x06\xb5\xb8\xe7\xc4\xf0\x41\x8f"
+                       "\xf0\xbd\x2f\x0b\xb9\x18\xf8\xde"
+                       "\x64\xb1\xdb\xee\x00\x50\x77\xe1"
+                       "\xc7\xff\xa6\xfa\xdd\x70\xf4\xe3"
+                       "\x93\xe9\x77\x35\x3d\x4b\x2f\x2b"
+                       "\x6d\x55\xf0\xfc\x88\x54\x4e\x89"
+                       "\xc1\x8a\x23\x31\x2d\x14\x2a\xb8"
+                       "\x1b\x15\xdd\x9e\x6e\x7b\xda\x05"
+                       "\x91\x7d\x62\x64\x96\x72\xde\xfc"
+                       "\xc1\xec\xf0\x23\x51\x6f\xdb\x5b"
+                       "\x1d\x08\x57\xce\x09\xb8\xf6\xcd"
+                       "\x8d\x95\xf2\x20\xbf\x0f\x20\x57"
+                       "\x98\x81\x84\x4f\x15\x5c\x76\xe7"
+                       "\x3e\x0a\x3a\x6c\xc4\x8a\xbe\x78"
+                       "\x74\x77\xc3\x09\x4b\x5d\x48\xe4"
+                       "\xc8\xcb\x0b\xea\x17\x28\xcf\xcf"
+                       "\x31\x32\x44\xa4\xe5\x0e\x1a\x98"
+                       "\x94\xc4\xf0\xff\xae\x3e\x44\xe8"
+                       "\xa5\xb3\xb5\x37\x2f\xe8\xaf\x6f"
+                       "\x28\xc1\x37\x5f\x31\xd2\xb9\x33"
+                       "\xb1\xb2\x52\x94\x75\x2c\x29\x59"
+                       "\x06\xc2\x25\xe8\x71\x65\x4e\xed"
+                       "\xc0\x9c\xb1\xbb\x25\xdc\x6c\xe7"
+                       "\x4b\xa5\x7a\x54\x7a\x60\xff\x7a"
+                       "\xe0\x50\x40\x96\x35\x63\xe4\x0b"
+                       "\x76\xbd\xa4\x65\x00\x1b\x57\x88"
+                       "\xae\xed\x39\x88\x42\x11\x3c\xed"
+                       "\x85\x67\x7d\xb9\x68\x82\xe9\x43"
+                       "\x3c\x47\x53\xfa\xe8\xf8\x9f\x1f"
+                       "\x9f\xef\x0f\xf7\x30\xd9\x30\x0e"
+                       "\xb9\x9f\x69\x18\x2f\x7e\xf8\xf8"
+                       "\xf8\x8c\x0f\xd4\x02\x4d\xea\xcd"
+                       "\x0a\x9c\x6f\x71\x6d\x5a\x4c\x60"
+                       "\xce\x20\x56\x32\xc6\xc5\x99\x1f"
+                       "\x09\xe6\x4e\x18\x1a\x15\x13\xa8"
+                       "\x7d\xb1\x6b\xc0\xb2\x6d\xf8\x26"
+                       "\x66\xf8\x3d\x18\x74\x70\x66\x7a"
+                       "\x34\x17\xde\xba\x47\xf1\x06\x18"
+                       "\xcb\xaf\xeb\x4a\x1e\x8f\xa7\x77"
+                       "\xe0\x3b\x78\x62\x66\xc9\x10\xea"
+                       "\x1f\xb7\x29\x0a\x45\xa1\x1d\x1e"
+                       "\x1d\xe2\x65\x61\x50\x9c\xd7\x05"
+                       "\xf2\x0b\x5b\x12\x61\x02\xc8\xe5"
+                       "\x63\x4f\x20\x0c\x07\x17\x33\x5e"
+                       "\x03\x9a\x53\x0f\x2e\x55\xfe\x50"
+                       "\x43\x7d\xd0\xb6\x7e\x5a\xda\xae"
+                       "\x58\xef\x15\xa9\x83\xd9\x46\xb1"
+                       "\x42\xaa\xf5\x02\x6c\xce\x92\x06"
+                       "\x1b\xdb\x66\x45\x91\x79\xc2\x2d"
+                       "\xe6\x53\xd3\x14\xfd\xbb\x44\x63"
+                       "\xc6\xd7\x3d\x7a\x0c\x75\x78\x9d"
+                       "\x5c\xa6\x39\xb3\xe5\x63\xca\x8b"
+                       "\xfe\xd3\xef\x60\x83\xf6\x8e\x70"
+                       "\xb6\x67\xc7\x77\xed\x23\xef\x4c"
+                       "\xf0\xed\x2d\x07\x59\x6f\xc1\x01"
+                       "\x34\x37\x08\xab\xd9\x1f\x09\xb1"
+                       "\xce\x5b\x17\xff\x74\xf8\x9c\xd5"
+                       "\x2c\x56\x39\x79\x0f\x69\x44\x75"
+                       "\x58\x27\x01\xc4\xbf\xa7\xa1\x1d"
+                       "\x90\x17\x77\x86\x5a\x3f\xd9\xd1"
+                       "\x0e\xa0\x10\xf8\xec\x1e\xa5\x7f"
+                       "\x5e\x36\xd1\xe3\x04\x2c\x70\xf7"
+                       "\x8e\xc0\x98\x2f\x6c\x94\x2b\x41"
+                       "\xb7\x60\x00\xb7\x2e\xb8\x02\x8d"
+                       "\xb8\xb0\xd3\x86\xba\x1d\xd7\x90"
+                       "\xd6\xb6\xe1\xfc\xd7\xd8\x28\x06"
+                       "\x63\x9b\xce\x61\x24\x79\xc0\x70"
+                       "\x52\xd0\xb6\xd4\x28\x95\x24\x87"
+                       "\x03\x1f\xb7\x9a\xda\xa3\xfb\x52"
+                       "\x5b\x68\xe7\x4c\x8c\x24\xe1\x42"
+                       "\xf7\xd5\xfd\xad\x06\x32\x9f\xba"
+                       "\xc1\xfc\xdd\xc6\xfc\xfc\xb3\x38"
+                       "\x74\x56\x58\x40\x02\x37\x52\x2c"
+                       "\x55\xcc\xb3\x9e\x7a\xe9\xd4\x38"
+                       "\x41\x5e\x0c\x35\xe2\x11\xd1\x13"
+                       "\xf8\xb7\x8d\x72\x6b\x22\x2a\xb0"
+                       "\xdb\x08\xba\x35\xb9\x3f\xc8\xd3"
+                       "\x24\x90\xec\x58\xd2\x09\xc7\x2d"
+                       "\xed\x38\x80\x36\x72\x43\x27\x49"
+                       "\x4a\x80\x8a\xa2\xe8\xd3\xda\x30"
+                       "\x7d\xb6\x82\x37\x86\x92\x86\x3e"
+                       "\x08\xb2\x28\x5a\x55\x44\x24\x7d"
+                       "\x40\x48\x8a\xb6\x89\x58\x08\xa0"
+                       "\xd6\x6d\x3a\x17\xbf\xf6\x54\xa2"
+                       "\xf5\xd3\x8c\x0f\x78\x12\x57\x8b"
+                       "\xd5\xc2\xfd\x58\x5b\x7f\x38\xe3"
+                       "\xcc\xb7\x7c\x48\xb3\x20\xe8\x81"
+                       "\x14\x32\x45\x05\xe0\xdb\x9f\x75"
+                       "\x85\xb4\x6a\xfc\x95\xe3\x54\x22"
+                       "\x12\xee\x30\xfe\xd8\x30\xef\x34"
+                       "\x50\xab\x46\x30\x98\x2f\xb7\xc0"
+                       "\x15\xa2\x83\xb6\xf2\x06\x21\xa2"
+                       "\xc3\x26\x37\x14\xd1\x4d\xb5\x10"
+                       "\x52\x76\x4d\x6a\xee\xb5\x2b\x15"
+                       "\xb7\xf9\x51\xe8\x2a\xaf\xc7\xfa"
+                       "\x77\xaf\xb0\x05\x4d\xd1\x68\x8e"
+                       "\x74\x05\x9f\x9d\x93\xa5\x3e\x7f"
+                       "\x4e\x5f\x9d\xcb\x09\xc7\x83\xe3"
+                       "\x02\x9d\x27\x1f\xef\x85\x05\x8d"
+                       "\xec\x55\x88\x0f\x0d\x7c\x4c\xe8"
+                       "\xa1\x75\xa0\xd8\x06\x47\x14\xef"
+                       "\xaa\x61\xcf\x26\x15\xad\xd8\xa3"
+                       "\xaa\x75\xf2\x78\x4a\x5a\x61\xdf"
+                       "\x8b\xc7\x04\xbc\xb2\x32\xd2\x7e"
+                       "\x42\xee\xb4\x2f\x51\xff\x7b\x2e"
+                       "\xd3\x02\xe8\xdc\x5d\x0d\x50\xdc"
+                       "\xae\xb7\x46\xf9\xa8\xe6\xd0\x16"
+                       "\xcc\xe6\x2c\x81\xc7\xad\xe9\xf0"
+                       "\x05\x72\x6d\x3d\x0a\x7a\xa9\x02"
+                       "\xac\x82\x93\x6e\xb6\x1c\x28\xfc"
+                       "\x44\x12\xfb\x73\x77\xd4\x13\x39"
+                       "\x29\x88\x8a\xf3\x5c\xa6\x36\xa0"
+                       "\x2a\xed\x7e\xb1\x1d\xd6\x4c\x6b"
+                       "\x41\x01\x18\x5d\x5d\x07\x97\xa6"
+                       "\x4b\xef\x31\x18\xea\xac\xb1\x84"
+                       "\x21\xed\xda\x86",
+               .rlen = 4100,
+               .np     = 2,
+               .tap    = { 4064, 36 },
+       },
+};
+
+static struct cipher_testvec aes_ctr_dec_tv_template[] = {
+       { /* From RFC 3686 */
+               .key    = "\xae\x68\x52\xf8\x12\x10\x67\xcc"
+                         "\x4b\xf7\xa5\x76\x55\x77\xf3\x9e"
+                         "\x00\x00\x00\x30",
+               .klen   = 20,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "\xe4\x09\x5d\x4f\xb7\xa7\xb3\x79"
+                         "\x2d\x61\x75\xa3\x26\x13\x11\xb8",
+               .ilen   = 16,
+               .result = "Single block msg",
+               .rlen   = 16,
+       }, {
+               .key    = "\x7e\x24\x06\x78\x17\xfa\xe0\xd7"
+                         "\x43\xd6\xce\x1f\x32\x53\x91\x63"
+                         "\x00\x6c\xb6\xdb",
+               .klen   = 20,
+               .iv     = "\xc0\x54\x3b\x59\xda\x48\xd9\x0b",
+               .input  = "\x51\x04\xa1\x06\x16\x8a\x72\xd9"
+                         "\x79\x0d\x41\xee\x8e\xda\xd3\x88"
+                         "\xeb\x2e\x1e\xfc\x46\xda\x57\xc8"
+                         "\xfc\xe6\x30\xdf\x91\x41\xbe\x28",
+               .ilen   = 32,
+               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .rlen   = 32,
+       }, {
+               .key    = "\x16\xaf\x5b\x14\x5f\xc9\xf5\x79"
+                         "\xc1\x75\xf9\x3e\x3b\xfb\x0e\xed"
+                         "\x86\x3d\x06\xcc\xfd\xb7\x85\x15"
+                         "\x00\x00\x00\x48",
+               .klen   = 28,
+               .iv     = "\x36\x73\x3c\x14\x7d\x6d\x93\xcb",
+               .input  = "\x4b\x55\x38\x4f\xe2\x59\xc9\xc8"
+                         "\x4e\x79\x35\xa0\x03\xcb\xe9\x28",
+               .ilen   = 16,
+               .result = "Single block msg",
+               .rlen   = 16,
+       }, {
+               .key    = "\x7c\x5c\xb2\x40\x1b\x3d\xc3\x3c"
+                         "\x19\xe7\x34\x08\x19\xe0\xf6\x9c"
+                         "\x67\x8c\x3d\xb8\xe6\xf6\xa9\x1a"
+                         "\x00\x96\xb0\x3b",
+               .klen   = 28,
+               .iv     = "\x02\x0c\x6e\xad\xc2\xcb\x50\x0d",
+               .input  = "\x45\x32\x43\xfc\x60\x9b\x23\x32"
+                         "\x7e\xdf\xaa\xfa\x71\x31\xcd\x9f"
+                         "\x84\x90\x70\x1c\x5a\xd4\xa7\x9c"
+                         "\xfc\x1f\xe0\xff\x42\xf4\xfb\x00",
+               .ilen   = 32,
+               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .rlen   = 32,
+       }, {
+               .key    = "\x77\x6b\xef\xf2\x85\x1d\xb0\x6f"
+                         "\x4c\x8a\x05\x42\xc8\x69\x6f\x6c"
+                         "\x6a\x81\xaf\x1e\xec\x96\xb4\xd3"
+                         "\x7f\xc1\xd6\x89\xe6\xc1\xc1\x04"
+                         "\x00\x00\x00\x60",
+               .klen   = 36,
+               .iv     = "\xdb\x56\x72\xc9\x7a\xa8\xf0\xb2",
+               .input  = "\x14\x5a\xd0\x1d\xbf\x82\x4e\xc7"
+                         "\x56\x08\x63\xdc\x71\xe3\xe0\xc0",
+               .ilen   = 16,
+               .result = "Single block msg",
+               .rlen   = 16,
+       }, {
+               .key    = "\xf6\xd6\x6d\x6b\xd5\x2d\x59\xbb"
+                         "\x07\x96\x36\x58\x79\xef\xf8\x86"
+                         "\xc6\x6d\xd5\x1a\x5b\x6a\x99\x74"
+                         "\x4b\x50\x59\x0c\x87\xa2\x38\x84"
+                         "\x00\xfa\xac\x24",
+               .klen   = 36,
+               .iv     = "\xc1\x58\x5e\xf1\x5a\x43\xd8\x75",
+               .input  = "\xf0\x5e\x23\x1b\x38\x94\x61\x2c"
+                         "\x49\xee\x00\x0b\x80\x4e\xb2\xa9"
+                         "\xb8\x30\x6b\x50\x8f\x83\x9d\x6a"
+                         "\x55\x30\x83\x1d\x93\x44\xaf\x1c",
+               .ilen   = 32,
+               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .rlen   = 32,
+       },
+};
+
+static struct aead_testvec aes_gcm_enc_tv_template[] = {
+       { /* From McGrew & Viega - http://citeseer.ist.psu.edu/656989.html */
+               .key    = zeroed_string,
+               .klen   = 16,
+               .result = "\x58\xe2\xfc\xce\xfa\x7e\x30\x61"
+                         "\x36\x7f\x1d\x57\xa4\xe7\x45\x5a",
+               .rlen   = 16,
+       }, {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .input  = zeroed_string,
+               .ilen   = 16,
+               .result = "\x03\x88\xda\xce\x60\xb6\xa3\x92"
+                         "\xf3\x28\xc2\xb9\x71\xb2\xfe\x78"
+                         "\xab\x6e\x47\xd4\x2c\xec\x13\xbd"
+                         "\xf5\x3a\x67\xb2\x12\x57\xbd\xdf",
+               .rlen   = 32,
+       }, {
+               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08",
+               .klen   = 16,
+               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+                         "\xde\xca\xf8\x88",
+               .input  = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+                         "\xba\x63\x7b\x39\x1a\xaf\xd2\x55",
+               .ilen   = 64,
+               .result = "\x42\x83\x1e\xc2\x21\x77\x74\x24"
+                         "\x4b\x72\x21\xb7\x84\xd0\xd4\x9c"
+                         "\xe3\xaa\x21\x2f\x2c\x02\xa4\xe0"
+                         "\x35\xc1\x7e\x23\x29\xac\xa1\x2e"
+                         "\x21\xd5\x14\xb2\x54\x66\x93\x1c"
+                         "\x7d\x8f\x6a\x5a\xac\x84\xaa\x05"
+                         "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97"
+                         "\x3d\x58\xe0\x91\x47\x3f\x59\x85"
+                         "\x4d\x5c\x2a\xf3\x27\xcd\x64\xa6"
+                         "\x2c\xf3\x5a\xbd\x2b\xa6\xfa\xb4",
+               .rlen   = 80,
+       }, {
+               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08",
+               .klen   = 16,
+               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+                         "\xde\xca\xf8\x88",
+               .input  = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+                         "\xba\x63\x7b\x39",
+               .ilen   = 60,
+               .assoc  = "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+                         "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+                         "\xab\xad\xda\xd2",
+               .alen   = 20,
+               .result = "\x42\x83\x1e\xc2\x21\x77\x74\x24"
+                         "\x4b\x72\x21\xb7\x84\xd0\xd4\x9c"
+                         "\xe3\xaa\x21\x2f\x2c\x02\xa4\xe0"
+                         "\x35\xc1\x7e\x23\x29\xac\xa1\x2e"
+                         "\x21\xd5\x14\xb2\x54\x66\x93\x1c"
+                         "\x7d\x8f\x6a\x5a\xac\x84\xaa\x05"
+                         "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97"
+                         "\x3d\x58\xe0\x91"
+                         "\x5b\xc9\x4f\xbc\x32\x21\xa5\xdb"
+                         "\x94\xfa\xe9\x5a\xe7\x12\x1a\x47",
+               .rlen   = 76,
+       }, {
+               .key    = zeroed_string,
+               .klen   = 24,
+               .result = "\xcd\x33\xb2\x8a\xc7\x73\xf7\x4b"
+                         "\xa0\x0e\xd1\xf3\x12\x57\x24\x35",
+               .rlen   = 16,
+       }, {
+               .key    = zeroed_string,
+               .klen   = 24,
+               .input  = zeroed_string,
+               .ilen   = 16,
+               .result = "\x98\xe7\x24\x7c\x07\xf0\xfe\x41"
+                         "\x1c\x26\x7e\x43\x84\xb0\xf6\x00"
+                         "\x2f\xf5\x8d\x80\x03\x39\x27\xab"
+                         "\x8e\xf4\xd4\x58\x75\x14\xf0\xfb",
+               .rlen   = 32,
+       }, {
+               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+                         "\xfe\xff\xe9\x92\x86\x65\x73\x1c",
+               .klen   = 24,
+               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+                         "\xde\xca\xf8\x88",
+               .input  = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+                         "\xba\x63\x7b\x39\x1a\xaf\xd2\x55",
+               .ilen   = 64,
+               .result = "\x39\x80\xca\x0b\x3c\x00\xe8\x41"
+                         "\xeb\x06\xfa\xc4\x87\x2a\x27\x57"
+                         "\x85\x9e\x1c\xea\xa6\xef\xd9\x84"
+                         "\x62\x85\x93\xb4\x0c\xa1\xe1\x9c"
+                         "\x7d\x77\x3d\x00\xc1\x44\xc5\x25"
+                         "\xac\x61\x9d\x18\xc8\x4a\x3f\x47"
+                         "\x18\xe2\x44\x8b\x2f\xe3\x24\xd9"
+                         "\xcc\xda\x27\x10\xac\xad\xe2\x56"
+                         "\x99\x24\xa7\xc8\x58\x73\x36\xbf"
+                         "\xb1\x18\x02\x4d\xb8\x67\x4a\x14",
+               .rlen   = 80,
+       }, {
+               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+                         "\xfe\xff\xe9\x92\x86\x65\x73\x1c",
+               .klen   = 24,
+               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+                         "\xde\xca\xf8\x88",
+               .input  = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+                         "\xba\x63\x7b\x39",
+               .ilen   = 60,
+               .assoc  = "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+                         "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+                         "\xab\xad\xda\xd2",
+               .alen   = 20,
+               .result = "\x39\x80\xca\x0b\x3c\x00\xe8\x41"
+                         "\xeb\x06\xfa\xc4\x87\x2a\x27\x57"
+                         "\x85\x9e\x1c\xea\xa6\xef\xd9\x84"
+                         "\x62\x85\x93\xb4\x0c\xa1\xe1\x9c"
+                         "\x7d\x77\x3d\x00\xc1\x44\xc5\x25"
+                         "\xac\x61\x9d\x18\xc8\x4a\x3f\x47"
+                         "\x18\xe2\x44\x8b\x2f\xe3\x24\xd9"
+                         "\xcc\xda\x27\x10"
+                         "\x25\x19\x49\x8e\x80\xf1\x47\x8f"
+                         "\x37\xba\x55\xbd\x6d\x27\x61\x8c",
+               .rlen   = 76,
+               .np     = 2,
+               .tap    = { 32, 28 },
+               .anp    = 2,
+               .atap   = { 8, 12 }
+       }, {
+               .key    = zeroed_string,
+               .klen   = 32,
+               .result = "\x53\x0f\x8a\xfb\xc7\x45\x36\xb9"
+                         "\xa9\x63\xb4\xf1\xc4\xcb\x73\x8b",
+               .rlen   = 16,
+       }
+};
+
+static struct aead_testvec aes_gcm_dec_tv_template[] = {
+       { /* From McGrew & Viega - http://citeseer.ist.psu.edu/656989.html */
+               .key    = zeroed_string,
+               .klen   = 32,
+               .input  = "\xce\xa7\x40\x3d\x4d\x60\x6b\x6e"
+                         "\x07\x4e\xc5\xd3\xba\xf3\x9d\x18"
+                         "\xd0\xd1\xc8\xa7\x99\x99\x6b\xf0"
+                         "\x26\x5b\x98\xb5\xd4\x8a\xb9\x19",
+               .ilen   = 32,
+               .result  = zeroed_string,
+               .rlen   = 16,
+       }, {
+               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+                         "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08",
+               .klen   = 32,
+               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+                         "\xde\xca\xf8\x88",
+               .input  = "\x52\x2d\xc1\xf0\x99\x56\x7d\x07"
+                         "\xf4\x7f\x37\xa3\x2a\x84\x42\x7d"
+                         "\x64\x3a\x8c\xdc\xbf\xe5\xc0\xc9"
+                         "\x75\x98\xa2\xbd\x25\x55\xd1\xaa"
+                         "\x8c\xb0\x8e\x48\x59\x0d\xbb\x3d"
+                         "\xa7\xb0\x8b\x10\x56\x82\x88\x38"
+                         "\xc5\xf6\x1e\x63\x93\xba\x7a\x0a"
+                         "\xbc\xc9\xf6\x62\x89\x80\x15\xad"
+                         "\xb0\x94\xda\xc5\xd9\x34\x71\xbd"
+                         "\xec\x1a\x50\x22\x70\xe3\xcc\x6c",
+               .ilen   = 80,
+               .result = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+                         "\xba\x63\x7b\x39\x1a\xaf\xd2\x55",
+               .rlen   = 64,
+       }, {
+               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+                         "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08",
+               .klen   = 32,
+               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+                         "\xde\xca\xf8\x88",
+               .input  = "\x52\x2d\xc1\xf0\x99\x56\x7d\x07"
+                         "\xf4\x7f\x37\xa3\x2a\x84\x42\x7d"
+                         "\x64\x3a\x8c\xdc\xbf\xe5\xc0\xc9"
+                         "\x75\x98\xa2\xbd\x25\x55\xd1\xaa"
+                         "\x8c\xb0\x8e\x48\x59\x0d\xbb\x3d"
+                         "\xa7\xb0\x8b\x10\x56\x82\x88\x38"
+                         "\xc5\xf6\x1e\x63\x93\xba\x7a\x0a"
+                         "\xbc\xc9\xf6\x62"
+                         "\x76\xfc\x6e\xce\x0f\x4e\x17\x68"
+                         "\xcd\xdf\x88\x53\xbb\x2d\x55\x1b",
+               .ilen   = 76,
+               .assoc  = "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+                         "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+                         "\xab\xad\xda\xd2",
+               .alen   = 20,
+               .result = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+                         "\xba\x63\x7b\x39",
+               .rlen   = 60,
+               .np     = 2,
+               .tap    = { 48, 28 },
+               .anp    = 3,
+               .atap   = { 8, 8, 4 }
+       }, {
+               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08",
+               .klen   = 16,
+               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+                         "\xde\xca\xf8\x88",
+               .input  = "\x42\x83\x1e\xc2\x21\x77\x74\x24"
+                         "\x4b\x72\x21\xb7\x84\xd0\xd4\x9c"
+                         "\xe3\xaa\x21\x2f\x2c\x02\xa4\xe0"
+                         "\x35\xc1\x7e\x23\x29\xac\xa1\x2e"
+                         "\x21\xd5\x14\xb2\x54\x66\x93\x1c"
+                         "\x7d\x8f\x6a\x5a\xac\x84\xaa\x05"
+                         "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97"
+                         "\x3d\x58\xe0\x91\x47\x3f\x59\x85"
+                         "\x4d\x5c\x2a\xf3\x27\xcd\x64\xa6"
+                         "\x2c\xf3\x5a\xbd\x2b\xa6\xfa\xb4",
+               .ilen   = 80,
+               .result = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+                         "\xba\x63\x7b\x39\x1a\xaf\xd2\x55",
+               .rlen   = 64,
+       }, {
+               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08",
+               .klen   = 16,
+               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+                         "\xde\xca\xf8\x88",
+               .input  = "\x42\x83\x1e\xc2\x21\x77\x74\x24"
+                         "\x4b\x72\x21\xb7\x84\xd0\xd4\x9c"
+                         "\xe3\xaa\x21\x2f\x2c\x02\xa4\xe0"
+                         "\x35\xc1\x7e\x23\x29\xac\xa1\x2e"
+                         "\x21\xd5\x14\xb2\x54\x66\x93\x1c"
+                         "\x7d\x8f\x6a\x5a\xac\x84\xaa\x05"
+                         "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97"
+                         "\x3d\x58\xe0\x91"
+                         "\x5b\xc9\x4f\xbc\x32\x21\xa5\xdb"
+                         "\x94\xfa\xe9\x5a\xe7\x12\x1a\x47",
+               .ilen   = 76,
+               .assoc  = "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+                         "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+                         "\xab\xad\xda\xd2",
+               .alen   = 20,
+               .result = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+                         "\xba\x63\x7b\x39",
+               .rlen   = 60,
+       }, {
+               .key    = zeroed_string,
+               .klen   = 24,
+               .input  = "\x98\xe7\x24\x7c\x07\xf0\xfe\x41"
+                         "\x1c\x26\x7e\x43\x84\xb0\xf6\x00"
+                         "\x2f\xf5\x8d\x80\x03\x39\x27\xab"
+                         "\x8e\xf4\xd4\x58\x75\x14\xf0\xfb",
+               .ilen   = 32,
+               .result  = zeroed_string,
+               .rlen   = 16,
+       }, {
+               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+                         "\xfe\xff\xe9\x92\x86\x65\x73\x1c",
+               .klen   = 24,
+               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+                         "\xde\xca\xf8\x88",
+               .input  = "\x39\x80\xca\x0b\x3c\x00\xe8\x41"
+                         "\xeb\x06\xfa\xc4\x87\x2a\x27\x57"
+                         "\x85\x9e\x1c\xea\xa6\xef\xd9\x84"
+                         "\x62\x85\x93\xb4\x0c\xa1\xe1\x9c"
+                         "\x7d\x77\x3d\x00\xc1\x44\xc5\x25"
+                         "\xac\x61\x9d\x18\xc8\x4a\x3f\x47"
+                         "\x18\xe2\x44\x8b\x2f\xe3\x24\xd9"
+                         "\xcc\xda\x27\x10\xac\xad\xe2\x56"
+                         "\x99\x24\xa7\xc8\x58\x73\x36\xbf"
+                         "\xb1\x18\x02\x4d\xb8\x67\x4a\x14",
+               .ilen   = 80,
+               .result = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+                         "\xba\x63\x7b\x39\x1a\xaf\xd2\x55",
+               .rlen   = 64,
+       }, {
+               .key    = "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
+                         "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+                         "\xfe\xff\xe9\x92\x86\x65\x73\x1c",
+               .klen   = 24,
+               .iv     = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
+                         "\xde\xca\xf8\x88",
+               .input  = "\x39\x80\xca\x0b\x3c\x00\xe8\x41"
+                         "\xeb\x06\xfa\xc4\x87\x2a\x27\x57"
+                         "\x85\x9e\x1c\xea\xa6\xef\xd9\x84"
+                         "\x62\x85\x93\xb4\x0c\xa1\xe1\x9c"
+                         "\x7d\x77\x3d\x00\xc1\x44\xc5\x25"
+                         "\xac\x61\x9d\x18\xc8\x4a\x3f\x47"
+                         "\x18\xe2\x44\x8b\x2f\xe3\x24\xd9"
+                         "\xcc\xda\x27\x10"
+                         "\x25\x19\x49\x8e\x80\xf1\x47\x8f"
+                         "\x37\xba\x55\xbd\x6d\x27\x61\x8c",
+               .ilen   = 76,
+               .assoc  = "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+                         "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+                         "\xab\xad\xda\xd2",
+               .alen   = 20,
+               .result = "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
+                         "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+                         "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
+                         "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+                         "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
+                         "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+                         "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
+                         "\xba\x63\x7b\x39",
+               .rlen   = 60,
+       }
+};
+
+static struct aead_testvec aes_ccm_enc_tv_template[] = {
+       { /* From RFC 3610 */
+               .key    = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
+               .klen   = 16,
+               .iv     = "\x01\x00\x00\x00\x03\x02\x01\x00"
+                         "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
+               .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07",
+               .alen   = 8,
+               .input  = "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e",
+               .ilen   = 23,
+               .result = "\x58\x8c\x97\x9a\x61\xc6\x63\xd2"
+                         "\xf0\x66\xd0\xc2\xc0\xf9\x89\x80"
+                         "\x6d\x5f\x6b\x61\xda\xc3\x84\x17"
+                         "\xe8\xd1\x2c\xfd\xf9\x26\xe0",
+               .rlen   = 31,
+       }, {
+               .key    = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
+               .klen   = 16,
+               .iv     = "\x01\x00\x00\x00\x07\x06\x05\x04"
+                         "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
+               .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b",
+               .alen   = 12,
+               .input  = "\x0c\x0d\x0e\x0f\x10\x11\x12\x13"
+                         "\x14\x15\x16\x17\x18\x19\x1a\x1b"
+                         "\x1c\x1d\x1e\x1f",
+               .ilen   = 20,
+               .result = "\xdc\xf1\xfb\x7b\x5d\x9e\x23\xfb"
+                         "\x9d\x4e\x13\x12\x53\x65\x8a\xd8"
+                         "\x6e\xbd\xca\x3e\x51\xe8\x3f\x07"
+                         "\x7d\x9c\x2d\x93",
+               .rlen   = 28,
+       }, {
+               .key    = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
+               .klen   = 16,
+               .iv     = "\x01\x00\x00\x00\x0b\x0a\x09\x08"
+                         "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
+               .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07",
+               .alen   = 8,
+               .input  = "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+                         "\x20",
+               .ilen   = 25,
+               .result = "\x82\x53\x1a\x60\xcc\x24\x94\x5a"
+                         "\x4b\x82\x79\x18\x1a\xb5\xc8\x4d"
+                         "\xf2\x1c\xe7\xf9\xb7\x3f\x42\xe1"
+                         "\x97\xea\x9c\x07\xe5\x6b\x5e\xb1"
+                         "\x7e\x5f\x4e",
+               .rlen   = 35,
+       }, {
+               .key    = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
+               .klen   = 16,
+               .iv     = "\x01\x00\x00\x00\x0c\x0b\x0a\x09"
+                         "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
+               .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b",
+               .alen   = 12,
+               .input  = "\x0c\x0d\x0e\x0f\x10\x11\x12\x13"
+                         "\x14\x15\x16\x17\x18\x19\x1a\x1b"
+                         "\x1c\x1d\x1e",
+               .ilen   = 19,
+               .result = "\x07\x34\x25\x94\x15\x77\x85\x15"
+                         "\x2b\x07\x40\x98\x33\x0a\xbb\x14"
+                         "\x1b\x94\x7b\x56\x6a\xa9\x40\x6b"
+                         "\x4d\x99\x99\x88\xdd",
+               .rlen   = 29,
+       }, {
+               .key    = "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3"
+                         "\x25\xa7\x62\x36\xdf\x93\xcc\x6b",
+               .klen   = 16,
+               .iv     = "\x01\x00\x33\x56\x8e\xf7\xb2\x63"
+                         "\x3c\x96\x96\x76\x6c\xfa\x00\x00",
+               .assoc  = "\x63\x01\x8f\x76\xdc\x8a\x1b\xcb",
+               .alen   = 8,
+               .input  = "\x90\x20\xea\x6f\x91\xbd\xd8\x5a"
+                         "\xfa\x00\x39\xba\x4b\xaf\xf9\xbf"
+                         "\xb7\x9c\x70\x28\x94\x9c\xd0\xec",
+               .ilen   = 24,
+               .result = "\x4c\xcb\x1e\x7c\xa9\x81\xbe\xfa"
+                         "\xa0\x72\x6c\x55\xd3\x78\x06\x12"
+                         "\x98\xc8\x5c\x92\x81\x4a\xbc\x33"
+                         "\xc5\x2e\xe8\x1d\x7d\x77\xc0\x8a",
+               .rlen   = 32,
+       }, {
+               .key    = "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3"
+                         "\x25\xa7\x62\x36\xdf\x93\xcc\x6b",
+               .klen   = 16,
+               .iv     = "\x01\x00\xd5\x60\x91\x2d\x3f\x70"
+                         "\x3c\x96\x96\x76\x6c\xfa\x00\x00",
+               .assoc  = "\xcd\x90\x44\xd2\xb7\x1f\xdb\x81"
+                         "\x20\xea\x60\xc0",
+               .alen   = 12,
+               .input  = "\x64\x35\xac\xba\xfb\x11\xa8\x2e"
+                         "\x2f\x07\x1d\x7c\xa4\xa5\xeb\xd9"
+                         "\x3a\x80\x3b\xa8\x7f",
+               .ilen   = 21,
+               .result = "\x00\x97\x69\xec\xab\xdf\x48\x62"
+                         "\x55\x94\xc5\x92\x51\xe6\x03\x57"
+                         "\x22\x67\x5e\x04\xc8\x47\x09\x9e"
+                         "\x5a\xe0\x70\x45\x51",
+               .rlen   = 29,
+       }, {
+               .key    = "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3"
+                         "\x25\xa7\x62\x36\xdf\x93\xcc\x6b",
+               .klen   = 16,
+               .iv     = "\x01\x00\x42\xff\xf8\xf1\x95\x1c"
+                         "\x3c\x96\x96\x76\x6c\xfa\x00\x00",
+               .assoc  = "\xd8\x5b\xc7\xe6\x9f\x94\x4f\xb8",
+               .alen   = 8,
+               .input  = "\x8a\x19\xb9\x50\xbc\xf7\x1a\x01"
+                         "\x8e\x5e\x67\x01\xc9\x17\x87\x65"
+                         "\x98\x09\xd6\x7d\xbe\xdd\x18",
+               .ilen   = 23,
+               .result = "\xbc\x21\x8d\xaa\x94\x74\x27\xb6"
+                         "\xdb\x38\x6a\x99\xac\x1a\xef\x23"
+                         "\xad\xe0\xb5\x29\x39\xcb\x6a\x63"
+                         "\x7c\xf9\xbe\xc2\x40\x88\x97\xc6"
+                         "\xba",
+               .rlen   = 33,
+       },
+};
+
+static struct aead_testvec aes_ccm_dec_tv_template[] = {
+       { /* From RFC 3610 */
+               .key    = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
+               .klen   = 16,
+               .iv     = "\x01\x00\x00\x00\x03\x02\x01\x00"
+                         "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
+               .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07",
+               .alen   = 8,
+               .input  = "\x58\x8c\x97\x9a\x61\xc6\x63\xd2"
+                         "\xf0\x66\xd0\xc2\xc0\xf9\x89\x80"
+                         "\x6d\x5f\x6b\x61\xda\xc3\x84\x17"
+                         "\xe8\xd1\x2c\xfd\xf9\x26\xe0",
+               .ilen   = 31,
+               .result = "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e",
+               .rlen   = 23,
+       }, {
+               .key    = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
+               .klen   = 16,
+               .iv     = "\x01\x00\x00\x00\x07\x06\x05\x04"
+                         "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
+               .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b",
+               .alen   = 12,
+               .input  = "\xdc\xf1\xfb\x7b\x5d\x9e\x23\xfb"
+                         "\x9d\x4e\x13\x12\x53\x65\x8a\xd8"
+                         "\x6e\xbd\xca\x3e\x51\xe8\x3f\x07"
+                         "\x7d\x9c\x2d\x93",
+               .ilen   = 28,
+               .result = "\x0c\x0d\x0e\x0f\x10\x11\x12\x13"
+                         "\x14\x15\x16\x17\x18\x19\x1a\x1b"
+                         "\x1c\x1d\x1e\x1f",
+               .rlen   = 20,
+       }, {
+               .key    = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
+               .klen   = 16,
+               .iv     = "\x01\x00\x00\x00\x0b\x0a\x09\x08"
+                         "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
+               .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07",
+               .alen   = 8,
+               .input  = "\x82\x53\x1a\x60\xcc\x24\x94\x5a"
+                         "\x4b\x82\x79\x18\x1a\xb5\xc8\x4d"
+                         "\xf2\x1c\xe7\xf9\xb7\x3f\x42\xe1"
+                         "\x97\xea\x9c\x07\xe5\x6b\x5e\xb1"
+                         "\x7e\x5f\x4e",
+               .ilen   = 35,
+               .result = "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+                         "\x20",
+               .rlen   = 25,
+       }, {
+               .key    = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+                         "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
+               .klen   = 16,
+               .iv     = "\x01\x00\x00\x00\x0c\x0b\x0a\x09"
+                         "\xa0\xa1\xa2\xa3\xa4\xa5\x00\x00",
+               .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b",
+               .alen   = 12,
+               .input  = "\x07\x34\x25\x94\x15\x77\x85\x15"
+                         "\x2b\x07\x40\x98\x33\x0a\xbb\x14"
+                         "\x1b\x94\x7b\x56\x6a\xa9\x40\x6b"
+                         "\x4d\x99\x99\x88\xdd",
+               .ilen   = 29,
+               .result = "\x0c\x0d\x0e\x0f\x10\x11\x12\x13"
+                         "\x14\x15\x16\x17\x18\x19\x1a\x1b"
+                         "\x1c\x1d\x1e",
+               .rlen   = 19,
+       }, {
+               .key    = "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3"
+                         "\x25\xa7\x62\x36\xdf\x93\xcc\x6b",
+               .klen   = 16,
+               .iv     = "\x01\x00\x33\x56\x8e\xf7\xb2\x63"
+                         "\x3c\x96\x96\x76\x6c\xfa\x00\x00",
+               .assoc  = "\x63\x01\x8f\x76\xdc\x8a\x1b\xcb",
+               .alen   = 8,
+               .input  = "\x4c\xcb\x1e\x7c\xa9\x81\xbe\xfa"
+                         "\xa0\x72\x6c\x55\xd3\x78\x06\x12"
+                         "\x98\xc8\x5c\x92\x81\x4a\xbc\x33"
+                         "\xc5\x2e\xe8\x1d\x7d\x77\xc0\x8a",
+               .ilen   = 32,
+               .result = "\x90\x20\xea\x6f\x91\xbd\xd8\x5a"
+                         "\xfa\x00\x39\xba\x4b\xaf\xf9\xbf"
+                         "\xb7\x9c\x70\x28\x94\x9c\xd0\xec",
+               .rlen   = 24,
+       }, {
+               .key    = "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3"
+                         "\x25\xa7\x62\x36\xdf\x93\xcc\x6b",
+               .klen   = 16,
+               .iv     = "\x01\x00\xd5\x60\x91\x2d\x3f\x70"
+                         "\x3c\x96\x96\x76\x6c\xfa\x00\x00",
+               .assoc  = "\xcd\x90\x44\xd2\xb7\x1f\xdb\x81"
+                         "\x20\xea\x60\xc0",
+               .alen   = 12,
+               .input  = "\x00\x97\x69\xec\xab\xdf\x48\x62"
+                         "\x55\x94\xc5\x92\x51\xe6\x03\x57"
+                         "\x22\x67\x5e\x04\xc8\x47\x09\x9e"
+                         "\x5a\xe0\x70\x45\x51",
+               .ilen   = 29,
+               .result = "\x64\x35\xac\xba\xfb\x11\xa8\x2e"
+                         "\x2f\x07\x1d\x7c\xa4\xa5\xeb\xd9"
+                         "\x3a\x80\x3b\xa8\x7f",
+               .rlen   = 21,
+       }, {
+               .key    = "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3"
+                         "\x25\xa7\x62\x36\xdf\x93\xcc\x6b",
+               .klen   = 16,
+               .iv     = "\x01\x00\x42\xff\xf8\xf1\x95\x1c"
+                         "\x3c\x96\x96\x76\x6c\xfa\x00\x00",
+               .assoc  = "\xd8\x5b\xc7\xe6\x9f\x94\x4f\xb8",
+               .alen   = 8,
+               .input  = "\xbc\x21\x8d\xaa\x94\x74\x27\xb6"
+                         "\xdb\x38\x6a\x99\xac\x1a\xef\x23"
+                         "\xad\xe0\xb5\x29\x39\xcb\x6a\x63"
+                         "\x7c\xf9\xbe\xc2\x40\x88\x97\xc6"
+                         "\xba",
+               .ilen   = 33,
+               .result = "\x8a\x19\xb9\x50\xbc\xf7\x1a\x01"
+                         "\x8e\x5e\x67\x01\xc9\x17\x87\x65"
+                         "\x98\x09\xd6\x7d\xbe\xdd\x18",
+               .rlen   = 23,
+       },
+};
+
+/* Cast5 test vectors from RFC 2144 */
+#define CAST5_ENC_TEST_VECTORS 3
+#define CAST5_DEC_TEST_VECTORS 3
+
+static struct cipher_testvec cast5_enc_tv_template[] = {
+       {
+               .key    = "\x01\x23\x45\x67\x12\x34\x56\x78"
+                         "\x23\x45\x67\x89\x34\x56\x78\x9a",
+               .klen   = 16,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .ilen   = 8,
+               .result = "\x23\x8b\x4f\xe5\x84\x7e\x44\xb2",
+               .rlen   = 8,
+       }, {
+               .key    = "\x01\x23\x45\x67\x12\x34\x56\x78"
+                         "\x23\x45",
+               .klen   = 10,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .ilen   = 8,
+               .result = "\xeb\x6a\x71\x1a\x2c\x02\x27\x1b",
+               .rlen   = 8,
+       }, {
+               .key    = "\x01\x23\x45\x67\x12",
+               .klen   = 5,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .ilen   = 8,
+               .result = "\x7a\xc8\x16\xd1\x6e\x9b\x30\x2e",
+               .rlen   = 8,
+       },
+};
+
+static struct cipher_testvec cast5_dec_tv_template[] = {
+       {
+               .key    = "\x01\x23\x45\x67\x12\x34\x56\x78"
+                         "\x23\x45\x67\x89\x34\x56\x78\x9a",
+               .klen   = 16,
+               .input  = "\x23\x8b\x4f\xe5\x84\x7e\x44\xb2",
+               .ilen   = 8,
+               .result = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .rlen   = 8,
+       }, {
+               .key    = "\x01\x23\x45\x67\x12\x34\x56\x78"
+                         "\x23\x45",
+               .klen   = 10,
+               .input  = "\xeb\x6a\x71\x1a\x2c\x02\x27\x1b",
+               .ilen   = 8,
+               .result = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .rlen   = 8,
+       }, {
+               .key    = "\x01\x23\x45\x67\x12",
+               .klen   = 5,
+               .input  = "\x7a\xc8\x16\xd1\x6e\x9b\x30\x2e",
+               .ilen   = 8,
+               .result = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .rlen   = 8,
+       },
+};
+
+/*
+ * ARC4 test vectors from OpenSSL
+ */
+#define ARC4_ENC_TEST_VECTORS  7
+#define ARC4_DEC_TEST_VECTORS  7
+
+static struct cipher_testvec arc4_enc_tv_template[] = {
+       {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .ilen   = 8,
+               .result = "\x75\xb7\x87\x80\x99\xe0\xc5\x96",
+               .rlen   = 8,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .ilen   = 8,
+               .result = "\x74\x94\xc2\xe7\x10\x4b\x08\x79",
+               .rlen   = 8,
+       }, {
+               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 8,
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .ilen   = 8,
+               .result = "\xde\x18\x89\x41\xa3\x37\x5d\x3a",
+               .rlen   = 8,
+       }, {
+               .key    = "\xef\x01\x23\x45",
+               .klen   = 4,
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00",
+               .ilen   = 20,
+               .result = "\xd6\xa1\x41\xa7\xec\x3c\x38\xdf"
+                         "\xbd\x61\x5a\x11\x62\xe1\xc7\xba"
+                         "\x36\xb6\x78\x58",
+               .rlen   = 20,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\x12\x34\x56\x78\x9A\xBC\xDE\xF0"
+                         "\x12\x34\x56\x78\x9A\xBC\xDE\xF0"
+                         "\x12\x34\x56\x78\x9A\xBC\xDE\xF0"
+                         "\x12\x34\x56\x78",
+               .ilen   = 28,
+               .result = "\x66\xa0\x94\x9f\x8a\xf7\xd6\x89"
+                         "\x1f\x7f\x83\x2b\xa8\x33\xc0\x0c"
+                         "\x89\x2e\xbe\x30\x14\x3c\xe2\x87"
+                         "\x40\x01\x1e\xcf",
+               .rlen   = 28,
+       }, {
+               .key    = "\xef\x01\x23\x45",
+               .klen   = 4,
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00",
+               .ilen   = 10,
+               .result = "\xd6\xa1\x41\xa7\xec\x3c\x38\xdf"
+                         "\xbd\x61",
+               .rlen   = 10,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xAB\xCD\xEF"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 16,
+               .input  = "\x01\x23\x45\x67\x89\xAB\xCD\xEF",
+               .ilen   = 8,
+               .result = "\x69\x72\x36\x59\x1B\x52\x42\xB1",
+               .rlen   = 8,
+       },
+};
+
+static struct cipher_testvec arc4_dec_tv_template[] = {
+       {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\x75\xb7\x87\x80\x99\xe0\xc5\x96",
+               .ilen   = 8,
+               .result = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .rlen   = 8,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\x74\x94\xc2\xe7\x10\x4b\x08\x79",
+               .ilen   = 8,
+               .result = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .rlen   = 8,
+       }, {
+               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 8,
+               .input  = "\xde\x18\x89\x41\xa3\x37\x5d\x3a",
+               .ilen   = 8,
+               .result = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .rlen   = 8,
+       }, {
+               .key    = "\xef\x01\x23\x45",
+               .klen   = 4,
+               .input  = "\xd6\xa1\x41\xa7\xec\x3c\x38\xdf"
+                         "\xbd\x61\x5a\x11\x62\xe1\xc7\xba"
+                         "\x36\xb6\x78\x58",
+               .ilen   = 20,
+               .result = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00",
+               .rlen   = 20,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef",
+               .klen   = 8,
+               .input  = "\x66\xa0\x94\x9f\x8a\xf7\xd6\x89"
+                         "\x1f\x7f\x83\x2b\xa8\x33\xc0\x0c"
+                         "\x89\x2e\xbe\x30\x14\x3c\xe2\x87"
+                         "\x40\x01\x1e\xcf",
+               .ilen   = 28,
+               .result = "\x12\x34\x56\x78\x9A\xBC\xDE\xF0"
+                         "\x12\x34\x56\x78\x9A\xBC\xDE\xF0"
+                         "\x12\x34\x56\x78\x9A\xBC\xDE\xF0"
+                         "\x12\x34\x56\x78",
+               .rlen   = 28,
+       }, {
+               .key    = "\xef\x01\x23\x45",
+               .klen   = 4,
+               .input  = "\xd6\xa1\x41\xa7\xec\x3c\x38\xdf"
+                         "\xbd\x61",
+               .ilen   = 10,
+               .result = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00",
+               .rlen   = 10,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xAB\xCD\xEF"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 16,
+               .input  = "\x69\x72\x36\x59\x1B\x52\x42\xB1",
+               .ilen   = 8,
+               .result = "\x01\x23\x45\x67\x89\xAB\xCD\xEF",
+               .rlen   = 8,
+       },
+};
+
+/*
+ * TEA test vectors
+ */
+#define TEA_ENC_TEST_VECTORS   4
+#define TEA_DEC_TEST_VECTORS   4
+
+static struct cipher_testvec tea_enc_tv_template[] = {
+       {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .input  = zeroed_string,
+               .ilen   = 8,
+               .result = "\x0a\x3a\xea\x41\x40\xa9\xba\x94",
+               .rlen   = 8,
+       }, {
+               .key    = "\x2b\x02\x05\x68\x06\x14\x49\x76"
+                         "\x77\x5d\x0e\x26\x6c\x28\x78\x43",
+               .klen   = 16,
+               .input  = "\x74\x65\x73\x74\x20\x6d\x65\x2e",
+               .ilen   = 8,
+               .result = "\x77\x5d\x2a\x6a\xf6\xce\x92\x09",
+               .rlen   = 8,
+       }, {
+               .key    = "\x09\x65\x43\x11\x66\x44\x39\x25"
+                         "\x51\x3a\x16\x10\x0a\x08\x12\x6e",
+               .klen   = 16,
+               .input  = "\x6c\x6f\x6e\x67\x65\x72\x5f\x74"
+                         "\x65\x73\x74\x5f\x76\x65\x63\x74",
+               .ilen   = 16,
+               .result = "\xbe\x7a\xbb\x81\x95\x2d\x1f\x1e"
+                         "\xdd\x89\xa1\x25\x04\x21\xdf\x95",
+               .rlen   = 16,
+       }, {
+               .key    = "\x4d\x76\x32\x17\x05\x3f\x75\x2c"
+                         "\x5d\x04\x16\x36\x15\x72\x63\x2f",
+               .klen   = 16,
+               .input  = "\x54\x65\x61\x20\x69\x73\x20\x67"
+                         "\x6f\x6f\x64\x20\x66\x6f\x72\x20"
+                         "\x79\x6f\x75\x21\x21\x21\x20\x72"
+                         "\x65\x61\x6c\x6c\x79\x21\x21\x21",
+               .ilen   = 32,
+               .result = "\xe0\x4d\x5d\x3c\xb7\x8c\x36\x47"
+                         "\x94\x18\x95\x91\xa9\xfc\x49\xf8"
+                         "\x44\xd1\x2d\xc2\x99\xb8\x08\x2a"
+                         "\x07\x89\x73\xc2\x45\x92\xc6\x90",
+               .rlen   = 32,
+       }
+};
+
+static struct cipher_testvec tea_dec_tv_template[] = {
+       {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .input  = "\x0a\x3a\xea\x41\x40\xa9\xba\x94",
+               .ilen   = 8,
+               .result = zeroed_string,
+               .rlen   = 8,
+       }, {
+               .key    = "\x2b\x02\x05\x68\x06\x14\x49\x76"
+                         "\x77\x5d\x0e\x26\x6c\x28\x78\x43",
+               .klen   = 16,
+               .input  = "\x77\x5d\x2a\x6a\xf6\xce\x92\x09",
+               .ilen   = 8,
+               .result = "\x74\x65\x73\x74\x20\x6d\x65\x2e",
+               .rlen   = 8,
+       }, {
+               .key    = "\x09\x65\x43\x11\x66\x44\x39\x25"
+                         "\x51\x3a\x16\x10\x0a\x08\x12\x6e",
+               .klen   = 16,
+               .input  = "\xbe\x7a\xbb\x81\x95\x2d\x1f\x1e"
+                         "\xdd\x89\xa1\x25\x04\x21\xdf\x95",
+               .ilen   = 16,
+               .result = "\x6c\x6f\x6e\x67\x65\x72\x5f\x74"
+                         "\x65\x73\x74\x5f\x76\x65\x63\x74",
+               .rlen   = 16,
+       }, {
+               .key    = "\x4d\x76\x32\x17\x05\x3f\x75\x2c"
+                         "\x5d\x04\x16\x36\x15\x72\x63\x2f",
+               .klen   = 16,
+               .input  = "\xe0\x4d\x5d\x3c\xb7\x8c\x36\x47"
+                         "\x94\x18\x95\x91\xa9\xfc\x49\xf8"
+                         "\x44\xd1\x2d\xc2\x99\xb8\x08\x2a"
+                         "\x07\x89\x73\xc2\x45\x92\xc6\x90",
+               .ilen   = 32,
+               .result = "\x54\x65\x61\x20\x69\x73\x20\x67"
+                         "\x6f\x6f\x64\x20\x66\x6f\x72\x20"
+                         "\x79\x6f\x75\x21\x21\x21\x20\x72"
+                         "\x65\x61\x6c\x6c\x79\x21\x21\x21",
+               .rlen   = 32,
+       }
+};
+
+/*
+ * XTEA test vectors
+ */
+#define XTEA_ENC_TEST_VECTORS  4
+#define XTEA_DEC_TEST_VECTORS  4
+
+static struct cipher_testvec xtea_enc_tv_template[] = {
+       {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .input  = zeroed_string,
+               .ilen   = 8,
+               .result = "\xd8\xd4\xe9\xde\xd9\x1e\x13\xf7",
+               .rlen   = 8,
+       }, {
+               .key    = "\x2b\x02\x05\x68\x06\x14\x49\x76"
+                         "\x77\x5d\x0e\x26\x6c\x28\x78\x43",
+               .klen   = 16,
+               .input  = "\x74\x65\x73\x74\x20\x6d\x65\x2e",
+               .ilen   = 8,
+               .result = "\x94\xeb\xc8\x96\x84\x6a\x49\xa8",
+               .rlen   = 8,
+       }, {
+               .key    = "\x09\x65\x43\x11\x66\x44\x39\x25"
+                         "\x51\x3a\x16\x10\x0a\x08\x12\x6e",
+               .klen   = 16,
+               .input  = "\x6c\x6f\x6e\x67\x65\x72\x5f\x74"
+                         "\x65\x73\x74\x5f\x76\x65\x63\x74",
+               .ilen   = 16,
+               .result = "\x3e\xce\xae\x22\x60\x56\xa8\x9d"
+                         "\x77\x4d\xd4\xb4\x87\x24\xe3\x9a",
+               .rlen   = 16,
+       }, {
+               .key    = "\x4d\x76\x32\x17\x05\x3f\x75\x2c"
+                         "\x5d\x04\x16\x36\x15\x72\x63\x2f",
+               .klen   = 16,
+               .input  = "\x54\x65\x61\x20\x69\x73\x20\x67"
+                         "\x6f\x6f\x64\x20\x66\x6f\x72\x20"
+                         "\x79\x6f\x75\x21\x21\x21\x20\x72"
+                         "\x65\x61\x6c\x6c\x79\x21\x21\x21",
+               .ilen   = 32,
+               .result = "\x99\x81\x9f\x5d\x6f\x4b\x31\x3a"
+                         "\x86\xff\x6f\xd0\xe3\x87\x70\x07"
+                         "\x4d\xb8\xcf\xf3\x99\x50\xb3\xd4"
+                         "\x73\xa2\xfa\xc9\x16\x59\x5d\x81",
+               .rlen   = 32,
+       }
+};
+
+static struct cipher_testvec xtea_dec_tv_template[] = {
+       {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .input  = "\xd8\xd4\xe9\xde\xd9\x1e\x13\xf7",
+               .ilen   = 8,
+               .result = zeroed_string,
+               .rlen   = 8,
+       }, {
+               .key    = "\x2b\x02\x05\x68\x06\x14\x49\x76"
+                         "\x77\x5d\x0e\x26\x6c\x28\x78\x43",
+               .klen   = 16,
+               .input  = "\x94\xeb\xc8\x96\x84\x6a\x49\xa8",
+               .ilen   = 8,
+               .result = "\x74\x65\x73\x74\x20\x6d\x65\x2e",
+               .rlen   = 8,
+       }, {
+               .key    = "\x09\x65\x43\x11\x66\x44\x39\x25"
+                         "\x51\x3a\x16\x10\x0a\x08\x12\x6e",
+               .klen   = 16,
+               .input  = "\x3e\xce\xae\x22\x60\x56\xa8\x9d"
+                         "\x77\x4d\xd4\xb4\x87\x24\xe3\x9a",
+               .ilen   = 16,
+               .result = "\x6c\x6f\x6e\x67\x65\x72\x5f\x74"
+                         "\x65\x73\x74\x5f\x76\x65\x63\x74",
+               .rlen   = 16,
+       }, {
+               .key    = "\x4d\x76\x32\x17\x05\x3f\x75\x2c"
+                         "\x5d\x04\x16\x36\x15\x72\x63\x2f",
+               .klen   = 16,
+               .input  = "\x99\x81\x9f\x5d\x6f\x4b\x31\x3a"
+                         "\x86\xff\x6f\xd0\xe3\x87\x70\x07"
+                         "\x4d\xb8\xcf\xf3\x99\x50\xb3\xd4"
+                         "\x73\xa2\xfa\xc9\x16\x59\x5d\x81",
+               .ilen   = 32,
+               .result = "\x54\x65\x61\x20\x69\x73\x20\x67"
+                         "\x6f\x6f\x64\x20\x66\x6f\x72\x20"
+                         "\x79\x6f\x75\x21\x21\x21\x20\x72"
+                         "\x65\x61\x6c\x6c\x79\x21\x21\x21",
+               .rlen   = 32,
+       }
+};
+
+/*
+ * KHAZAD test vectors.
+ */
+#define KHAZAD_ENC_TEST_VECTORS 5
+#define KHAZAD_DEC_TEST_VECTORS 5
+
+static struct cipher_testvec khazad_enc_tv_template[] = {
+       {
+               .key    = "\x80\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 16,
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .ilen   = 8,
+               .result = "\x49\xa4\xce\x32\xac\x19\x0e\x3f",
+               .rlen   = 8,
+       }, {
+               .key    = "\x38\x38\x38\x38\x38\x38\x38\x38"
+                         "\x38\x38\x38\x38\x38\x38\x38\x38",
+               .klen   = 16,
+               .input  = "\x38\x38\x38\x38\x38\x38\x38\x38",
+               .ilen   = 8,
+               .result = "\x7e\x82\x12\xa1\xd9\x5b\xe4\xf9",
+               .rlen   = 8,
+       }, {
+               .key    = "\xa2\xa2\xa2\xa2\xa2\xa2\xa2\xa2"
+                       "\xa2\xa2\xa2\xa2\xa2\xa2\xa2\xa2",
+               .klen   = 16,
+               .input  = "\xa2\xa2\xa2\xa2\xa2\xa2\xa2\xa2",
+               .ilen   = 8,
+               .result = "\xaa\xbe\xc1\x95\xc5\x94\x1a\x9c",
+               .rlen   = 8,
+       }, {
+               .key    = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f"
+                       "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
+               .klen   = 16,
+               .input  = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
+               .ilen   = 8,
+               .result = "\x04\x74\xf5\x70\x50\x16\xd3\xb8",
+               .rlen   = 8,
+       }, {
+               .key    = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f"
+                       "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
+               .klen   = 16,
+               .input  = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f"
+                       "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
+               .ilen   = 16,
+               .result = "\x04\x74\xf5\x70\x50\x16\xd3\xb8"
+                       "\x04\x74\xf5\x70\x50\x16\xd3\xb8",
+               .rlen   = 16,
+       },
+};
+
+static struct cipher_testvec khazad_dec_tv_template[] = {
+       {
+               .key    = "\x80\x00\x00\x00\x00\x00\x00\x00"
+                         "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 16,
+               .input  = "\x49\xa4\xce\x32\xac\x19\x0e\x3f",
+               .ilen   = 8,
+               .result = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .rlen   = 8,
+       }, {
+               .key    = "\x38\x38\x38\x38\x38\x38\x38\x38"
+                         "\x38\x38\x38\x38\x38\x38\x38\x38",
+               .klen   = 16,
+               .input  = "\x7e\x82\x12\xa1\xd9\x5b\xe4\xf9",
+               .ilen   = 8,
+               .result = "\x38\x38\x38\x38\x38\x38\x38\x38",
+               .rlen   = 8,
+       }, {
+               .key    = "\xa2\xa2\xa2\xa2\xa2\xa2\xa2\xa2"
+                       "\xa2\xa2\xa2\xa2\xa2\xa2\xa2\xa2",
+               .klen   = 16,
+               .input  = "\xaa\xbe\xc1\x95\xc5\x94\x1a\x9c",
+               .ilen   = 8,
+               .result = "\xa2\xa2\xa2\xa2\xa2\xa2\xa2\xa2",
+               .rlen   = 8,
+       }, {
+               .key    = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f"
+                       "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
+               .klen   = 16,
+               .input  = "\x04\x74\xf5\x70\x50\x16\xd3\xb8",
+               .ilen   = 8,
+               .result = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
+               .rlen   = 8,
+       }, {
+               .key    = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f"
+                       "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
+               .klen   = 16,
+               .input  = "\x04\x74\xf5\x70\x50\x16\xd3\xb8"
+                       "\x04\x74\xf5\x70\x50\x16\xd3\xb8",
+               .ilen   = 16,
+               .result = "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f"
+                       "\x2f\x2f\x2f\x2f\x2f\x2f\x2f\x2f",
+               .rlen   = 16,
+       },
+};
+
+/*
+ * Anubis test vectors.
+ */
+
+#define ANUBIS_ENC_TEST_VECTORS                        5
+#define ANUBIS_DEC_TEST_VECTORS                        5
+#define ANUBIS_CBC_ENC_TEST_VECTORS            2
+#define ANUBIS_CBC_DEC_TEST_VECTORS            2
+
+static struct cipher_testvec anubis_enc_tv_template[] = {
+       {
+               .key    = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
+               .klen   = 16,
+               .input  = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
+               .ilen   = 16,
+               .result = "\x6d\xc5\xda\xa2\x26\x7d\x62\x6f"
+                         "\x08\xb7\x52\x8e\x6e\x6e\x86\x90",
+               .rlen   = 16,
+       }, {
+
+               .key    = "\x03\x03\x03\x03\x03\x03\x03\x03"
+                         "\x03\x03\x03\x03\x03\x03\x03\x03"
+                         "\x03\x03\x03\x03",
+               .klen   = 20,
+               .input  = "\x03\x03\x03\x03\x03\x03\x03\x03"
+                         "\x03\x03\x03\x03\x03\x03\x03\x03",
+               .ilen   = 16,
+               .result = "\xdb\xf1\x42\xf4\xd1\x8a\xc7\x49"
+                         "\x87\x41\x6f\x82\x0a\x98\x64\xae",
+               .rlen   = 16,
+       }, {
+               .key    = "\x24\x24\x24\x24\x24\x24\x24\x24"
+                         "\x24\x24\x24\x24\x24\x24\x24\x24"
+                         "\x24\x24\x24\x24\x24\x24\x24\x24"
+                         "\x24\x24\x24\x24",
+               .klen   = 28,
+               .input  = "\x24\x24\x24\x24\x24\x24\x24\x24"
+                         "\x24\x24\x24\x24\x24\x24\x24\x24",
+               .ilen   = 16,
+               .result = "\xfd\x1b\x4a\xe3\xbf\xf0\xad\x3d"
+                         "\x06\xd3\x61\x27\xfd\x13\x9e\xde",
+               .rlen   = 16,
+       }, {
+               .key    = "\x25\x25\x25\x25\x25\x25\x25\x25"
+                         "\x25\x25\x25\x25\x25\x25\x25\x25"
+                         "\x25\x25\x25\x25\x25\x25\x25\x25"
+                         "\x25\x25\x25\x25\x25\x25\x25\x25",
+               .klen   = 32,
+               .input  = "\x25\x25\x25\x25\x25\x25\x25\x25"
+                         "\x25\x25\x25\x25\x25\x25\x25\x25",
+               .ilen   = 16,
+               .result = "\x1a\x91\xfb\x2b\xb7\x78\x6b\xc4"
+                       "\x17\xd9\xff\x40\x3b\x0e\xe5\xfe",
+               .rlen   = 16,
+       }, {
+               .key    = "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35",
+               .klen   = 40,
+               .input  = "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35",
+               .ilen   = 16,
+               .result = "\xa5\x2c\x85\x6f\x9c\xba\xa0\x97"
+                         "\x9e\xc6\x84\x0f\x17\x21\x07\xee",
+               .rlen   = 16,
+       },
+};
+
+static struct cipher_testvec anubis_dec_tv_template[] = {
+       {
+               .key    = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
+               .klen   = 16,
+               .input  = "\x6d\xc5\xda\xa2\x26\x7d\x62\x6f"
+                         "\x08\xb7\x52\x8e\x6e\x6e\x86\x90",
+               .ilen   = 16,
+               .result = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
+               .rlen   = 16,
+       }, {
+
+               .key    = "\x03\x03\x03\x03\x03\x03\x03\x03"
+                         "\x03\x03\x03\x03\x03\x03\x03\x03"
+                         "\x03\x03\x03\x03",
+               .klen   = 20,
+               .input  = "\xdb\xf1\x42\xf4\xd1\x8a\xc7\x49"
+                         "\x87\x41\x6f\x82\x0a\x98\x64\xae",
+               .ilen   = 16,
+               .result = "\x03\x03\x03\x03\x03\x03\x03\x03"
+                         "\x03\x03\x03\x03\x03\x03\x03\x03",
+               .rlen   = 16,
+       }, {
+               .key    = "\x24\x24\x24\x24\x24\x24\x24\x24"
+                         "\x24\x24\x24\x24\x24\x24\x24\x24"
+                         "\x24\x24\x24\x24\x24\x24\x24\x24"
+                         "\x24\x24\x24\x24",
+               .klen   = 28,
+               .input  = "\xfd\x1b\x4a\xe3\xbf\xf0\xad\x3d"
+                         "\x06\xd3\x61\x27\xfd\x13\x9e\xde",
+               .ilen   = 16,
+               .result = "\x24\x24\x24\x24\x24\x24\x24\x24"
+                         "\x24\x24\x24\x24\x24\x24\x24\x24",
+               .rlen   = 16,
+       }, {
+               .key    = "\x25\x25\x25\x25\x25\x25\x25\x25"
+                         "\x25\x25\x25\x25\x25\x25\x25\x25"
+                         "\x25\x25\x25\x25\x25\x25\x25\x25"
+                         "\x25\x25\x25\x25\x25\x25\x25\x25",
+               .klen   = 32,
+               .input  = "\x1a\x91\xfb\x2b\xb7\x78\x6b\xc4"
+                       "\x17\xd9\xff\x40\x3b\x0e\xe5\xfe",
+               .ilen   = 16,
+               .result = "\x25\x25\x25\x25\x25\x25\x25\x25"
+                         "\x25\x25\x25\x25\x25\x25\x25\x25",
+               .rlen   = 16,
+       }, {
+               .key    = "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35",
+               .input = "\xa5\x2c\x85\x6f\x9c\xba\xa0\x97"
+                        "\x9e\xc6\x84\x0f\x17\x21\x07\xee",
+               .klen   = 40,
+               .ilen   = 16,
+               .result = "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35",
+               .rlen   = 16,
+       },
+};
+
+static struct cipher_testvec anubis_cbc_enc_tv_template[] = {
+       {
+               .key    = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
+               .klen   = 16,
+               .input  = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
+               .ilen   = 32,
+               .result = "\x6d\xc5\xda\xa2\x26\x7d\x62\x6f"
+                         "\x08\xb7\x52\x8e\x6e\x6e\x86\x90"
+                         "\x86\xd8\xb5\x6f\x98\x5e\x8a\x66"
+                         "\x4f\x1f\x78\xa1\xbb\x37\xf1\xbe",
+               .rlen   = 32,
+       }, {
+               .key    = "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35",
+               .klen   = 40,
+               .input  = "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35",
+               .ilen   = 32,
+               .result = "\xa5\x2c\x85\x6f\x9c\xba\xa0\x97"
+                         "\x9e\xc6\x84\x0f\x17\x21\x07\xee"
+                         "\xa2\xbc\x06\x98\xc6\x4b\xda\x75"
+                         "\x2e\xaa\xbe\x58\xce\x01\x5b\xc7",
+               .rlen   = 32,
+       },
+};
+
+static struct cipher_testvec anubis_cbc_dec_tv_template[] = {
+       {
+               .key    = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
+               .klen   = 16,
+               .input  = "\x6d\xc5\xda\xa2\x26\x7d\x62\x6f"
+                         "\x08\xb7\x52\x8e\x6e\x6e\x86\x90"
+                         "\x86\xd8\xb5\x6f\x98\x5e\x8a\x66"
+                         "\x4f\x1f\x78\xa1\xbb\x37\xf1\xbe",
+               .ilen   = 32,
+               .result = "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
+                         "\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe",
+               .rlen   = 32,
+       }, {
+               .key    = "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35",
+               .klen   = 40,
+               .input = "\xa5\x2c\x85\x6f\x9c\xba\xa0\x97"
+                         "\x9e\xc6\x84\x0f\x17\x21\x07\xee"
+                         "\xa2\xbc\x06\x98\xc6\x4b\xda\x75"
+                         "\x2e\xaa\xbe\x58\xce\x01\x5b\xc7",
+               .ilen   = 32,
+               .result = "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35"
+                         "\x35\x35\x35\x35\x35\x35\x35\x35",
+               .rlen   = 32,
+       },
+};
+
+/*
+ * XETA test vectors
+ */
+#define XETA_ENC_TEST_VECTORS  4
+#define XETA_DEC_TEST_VECTORS  4
+
+static struct cipher_testvec xeta_enc_tv_template[] = {
+       {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .input  = zeroed_string,
+               .ilen   = 8,
+               .result = "\xaa\x22\x96\xe5\x6c\x61\xf3\x45",
+               .rlen   = 8,
+       }, {
+               .key    = "\x2b\x02\x05\x68\x06\x14\x49\x76"
+                         "\x77\x5d\x0e\x26\x6c\x28\x78\x43",
+               .klen   = 16,
+               .input  = "\x74\x65\x73\x74\x20\x6d\x65\x2e",
+               .ilen   = 8,
+               .result = "\x82\x3e\xeb\x35\xdc\xdd\xd9\xc3",
+               .rlen   = 8,
+       }, {
+               .key    = "\x09\x65\x43\x11\x66\x44\x39\x25"
+                         "\x51\x3a\x16\x10\x0a\x08\x12\x6e",
+               .klen   = 16,
+               .input  = "\x6c\x6f\x6e\x67\x65\x72\x5f\x74"
+                         "\x65\x73\x74\x5f\x76\x65\x63\x74",
+               .ilen   = 16,
+               .result = "\xe2\x04\xdb\xf2\x89\x85\x9e\xea"
+                         "\x61\x35\xaa\xed\xb5\xcb\x71\x2c",
+               .rlen   = 16,
+       }, {
+               .key    = "\x4d\x76\x32\x17\x05\x3f\x75\x2c"
+                         "\x5d\x04\x16\x36\x15\x72\x63\x2f",
+               .klen   = 16,
+               .input  = "\x54\x65\x61\x20\x69\x73\x20\x67"
+                         "\x6f\x6f\x64\x20\x66\x6f\x72\x20"
+                         "\x79\x6f\x75\x21\x21\x21\x20\x72"
+                         "\x65\x61\x6c\x6c\x79\x21\x21\x21",
+               .ilen   = 32,
+               .result = "\x0b\x03\xcd\x8a\xbe\x95\xfd\xb1"
+                         "\xc1\x44\x91\x0b\xa5\xc9\x1b\xb4"
+                         "\xa9\xda\x1e\x9e\xb1\x3e\x2a\x8f"
+                         "\xea\xa5\x6a\x85\xd1\xf4\xa8\xa5",
+               .rlen   = 32,
+       }
+};
+
+static struct cipher_testvec xeta_dec_tv_template[] = {
+       {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .input  = "\xaa\x22\x96\xe5\x6c\x61\xf3\x45",
+               .ilen   = 8,
+               .result = zeroed_string,
+               .rlen   = 8,
+       }, {
+               .key    = "\x2b\x02\x05\x68\x06\x14\x49\x76"
+                         "\x77\x5d\x0e\x26\x6c\x28\x78\x43",
+               .klen   = 16,
+               .input  = "\x82\x3e\xeb\x35\xdc\xdd\xd9\xc3",
+               .ilen   = 8,
+               .result = "\x74\x65\x73\x74\x20\x6d\x65\x2e",
+               .rlen   = 8,
+       }, {
+               .key    = "\x09\x65\x43\x11\x66\x44\x39\x25"
+                         "\x51\x3a\x16\x10\x0a\x08\x12\x6e",
+               .klen   = 16,
+               .input  = "\xe2\x04\xdb\xf2\x89\x85\x9e\xea"
+                         "\x61\x35\xaa\xed\xb5\xcb\x71\x2c",
+               .ilen   = 16,
+               .result = "\x6c\x6f\x6e\x67\x65\x72\x5f\x74"
+                         "\x65\x73\x74\x5f\x76\x65\x63\x74",
+               .rlen   = 16,
+       }, {
+               .key    = "\x4d\x76\x32\x17\x05\x3f\x75\x2c"
+                         "\x5d\x04\x16\x36\x15\x72\x63\x2f",
+               .klen   = 16,
+               .input  = "\x0b\x03\xcd\x8a\xbe\x95\xfd\xb1"
+                         "\xc1\x44\x91\x0b\xa5\xc9\x1b\xb4"
+                         "\xa9\xda\x1e\x9e\xb1\x3e\x2a\x8f"
+                         "\xea\xa5\x6a\x85\xd1\xf4\xa8\xa5",
+               .ilen   = 32,
+               .result = "\x54\x65\x61\x20\x69\x73\x20\x67"
+                         "\x6f\x6f\x64\x20\x66\x6f\x72\x20"
+                         "\x79\x6f\x75\x21\x21\x21\x20\x72"
+                         "\x65\x61\x6c\x6c\x79\x21\x21\x21",
+               .rlen   = 32,
+       }
+};
+
+/*
+ * FCrypt test vectors
+ */
+#define FCRYPT_ENC_TEST_VECTORS        ARRAY_SIZE(fcrypt_pcbc_enc_tv_template)
+#define FCRYPT_DEC_TEST_VECTORS        ARRAY_SIZE(fcrypt_pcbc_dec_tv_template)
+
+static struct cipher_testvec fcrypt_pcbc_enc_tv_template[] = {
+       { /* http://www.openafs.org/pipermail/openafs-devel/2000-December/005320.html */
+               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 8,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .ilen   = 8,
+               .result = "\x0E\x09\x00\xC7\x3E\xF7\xED\x41",
+               .rlen   = 8,
+       }, {
+               .key    = "\x11\x44\x77\xAA\xDD\x00\x33\x66",
+               .klen   = 8,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "\x12\x34\x56\x78\x9A\xBC\xDE\xF0",
+               .ilen   = 8,
+               .result = "\xD8\xED\x78\x74\x77\xEC\x06\x80",
+               .rlen   = 8,
+       }, { /* From Arla */
+               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+               .klen   = 8,
+               .iv     = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .input  = "The quick brown fox jumps over the lazy dogs.\0\0",
+               .ilen   = 48,
+               .result = "\x00\xf0\x0e\x11\x75\xe6\x23\x82"
+                         "\xee\xac\x98\x62\x44\x51\xe4\x84"
+                         "\xc3\x59\xd8\xaa\x64\x60\xae\xf7"
+                         "\xd2\xd9\x13\x79\x72\xa3\x45\x03"
+                         "\x23\xb5\x62\xd7\x0c\xf5\x27\xd1"
+                         "\xf8\x91\x3c\xac\x44\x22\x92\xef",
+               .rlen   = 48,
+       }, {
+               .key    = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .klen   = 8,
+               .iv     = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+               .input  = "The quick brown fox jumps over the lazy dogs.\0\0",
+               .ilen   = 48,
+               .result = "\xca\x90\xf5\x9d\xcb\xd4\xd2\x3c"
+                         "\x01\x88\x7f\x3e\x31\x6e\x62\x9d"
+                         "\xd8\xe0\x57\xa3\x06\x3a\x42\x58"
+                         "\x2a\x28\xfe\x72\x52\x2f\xdd\xe0"
+                         "\x19\x89\x09\x1c\x2a\x8e\x8c\x94"
+                         "\xfc\xc7\x68\xe4\x88\xaa\xde\x0f",
+               .rlen   = 48,
+       }, { /* split-page version */
+               .key    = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .klen   = 8,
+               .iv     = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+               .input  = "The quick brown fox jumps over the lazy dogs.\0\0",
+               .ilen   = 48,
+               .result = "\xca\x90\xf5\x9d\xcb\xd4\xd2\x3c"
+                         "\x01\x88\x7f\x3e\x31\x6e\x62\x9d"
+                         "\xd8\xe0\x57\xa3\x06\x3a\x42\x58"
+                         "\x2a\x28\xfe\x72\x52\x2f\xdd\xe0"
+                         "\x19\x89\x09\x1c\x2a\x8e\x8c\x94"
+                         "\xfc\xc7\x68\xe4\x88\xaa\xde\x0f",
+               .rlen   = 48,
+               .np     = 2,
+               .tap    = { 20, 28 },
+       }
+};
+
+static struct cipher_testvec fcrypt_pcbc_dec_tv_template[] = {
+       { /* http://www.openafs.org/pipermail/openafs-devel/2000-December/005320.html */
+               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 8,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "\x0E\x09\x00\xC7\x3E\xF7\xED\x41",
+               .ilen   = 8,
+               .result = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .rlen   = 8,
+       }, {
+               .key    = "\x11\x44\x77\xAA\xDD\x00\x33\x66",
+               .klen   = 8,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "\xD8\xED\x78\x74\x77\xEC\x06\x80",
+               .ilen   = 8,
+               .result = "\x12\x34\x56\x78\x9A\xBC\xDE\xF0",
+               .rlen   = 8,
+       }, { /* From Arla */
+               .key    = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+               .klen   = 8,
+               .iv     = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .input  = "\x00\xf0\x0e\x11\x75\xe6\x23\x82"
+                         "\xee\xac\x98\x62\x44\x51\xe4\x84"
+                         "\xc3\x59\xd8\xaa\x64\x60\xae\xf7"
+                         "\xd2\xd9\x13\x79\x72\xa3\x45\x03"
+                         "\x23\xb5\x62\xd7\x0c\xf5\x27\xd1"
+                         "\xf8\x91\x3c\xac\x44\x22\x92\xef",
+               .ilen   = 48,
+               .result = "The quick brown fox jumps over the lazy dogs.\0\0",
+               .rlen   = 48,
+       }, {
+               .key    = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .klen   = 8,
+               .iv     = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+               .input  = "\xca\x90\xf5\x9d\xcb\xd4\xd2\x3c"
+                         "\x01\x88\x7f\x3e\x31\x6e\x62\x9d"
+                         "\xd8\xe0\x57\xa3\x06\x3a\x42\x58"
+                         "\x2a\x28\xfe\x72\x52\x2f\xdd\xe0"
+                         "\x19\x89\x09\x1c\x2a\x8e\x8c\x94"
+                         "\xfc\xc7\x68\xe4\x88\xaa\xde\x0f",
+               .ilen   = 48,
+               .result = "The quick brown fox jumps over the lazy dogs.\0\0",
+               .rlen   = 48,
+       }, { /* split-page version */
+               .key    = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .klen   = 8,
+               .iv     = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
+               .input  = "\xca\x90\xf5\x9d\xcb\xd4\xd2\x3c"
+                         "\x01\x88\x7f\x3e\x31\x6e\x62\x9d"
+                         "\xd8\xe0\x57\xa3\x06\x3a\x42\x58"
+                         "\x2a\x28\xfe\x72\x52\x2f\xdd\xe0"
+                         "\x19\x89\x09\x1c\x2a\x8e\x8c\x94"
+                         "\xfc\xc7\x68\xe4\x88\xaa\xde\x0f",
+               .ilen   = 48,
+               .result = "The quick brown fox jumps over the lazy dogs.\0\0",
+               .rlen   = 48,
+               .np     = 2,
+               .tap    = { 20, 28 },
+       }
+};
+
+/*
+ * CAMELLIA test vectors.
+ */
+#define CAMELLIA_ENC_TEST_VECTORS 3
+#define CAMELLIA_DEC_TEST_VECTORS 3
+#define CAMELLIA_CBC_ENC_TEST_VECTORS 2
+#define CAMELLIA_CBC_DEC_TEST_VECTORS 2
+
+static struct cipher_testvec camellia_enc_tv_template[] = {
+       {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .klen   = 16,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .ilen   = 16,
+               .result = "\x67\x67\x31\x38\x54\x96\x69\x73"
+                         "\x08\x57\x06\x56\x48\xea\xbe\x43",
+               .rlen   = 16,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10"
+                         "\x00\x11\x22\x33\x44\x55\x66\x77",
+               .klen   = 24,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .ilen   = 16,
+               .result = "\xb4\x99\x34\x01\xb3\xe9\x96\xf8"
+                         "\x4e\xe5\xce\xe7\xd7\x9b\x09\xb9",
+               .rlen   = 16,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10"
+                         "\x00\x11\x22\x33\x44\x55\x66\x77"
+                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+               .klen   = 32,
+               .input  = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .ilen   = 16,
+               .result = "\x9a\xcc\x23\x7d\xff\x16\xd7\x6c"
+                         "\x20\xef\x7c\x91\x9e\x3a\x75\x09",
+               .rlen   = 16,
+       },
+};
+
+static struct cipher_testvec camellia_dec_tv_template[] = {
+       {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .klen   = 16,
+               .input  = "\x67\x67\x31\x38\x54\x96\x69\x73"
+                         "\x08\x57\x06\x56\x48\xea\xbe\x43",
+               .ilen   = 16,
+               .result = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .rlen   = 16,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10"
+                         "\x00\x11\x22\x33\x44\x55\x66\x77",
+               .klen   = 24,
+               .input  = "\xb4\x99\x34\x01\xb3\xe9\x96\xf8"
+                         "\x4e\xe5\xce\xe7\xd7\x9b\x09\xb9",
+               .ilen   = 16,
+               .result = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .rlen   = 16,
+       }, {
+               .key    = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10"
+                         "\x00\x11\x22\x33\x44\x55\x66\x77"
+                         "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+               .klen   = 32,
+               .input  = "\x9a\xcc\x23\x7d\xff\x16\xd7\x6c"
+                         "\x20\xef\x7c\x91\x9e\x3a\x75\x09",
+               .ilen   = 16,
+               .result = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+                         "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+               .rlen   = 16,
+       },
+};
+
+static struct cipher_testvec camellia_cbc_enc_tv_template[] = {
+       {
+               .key    = "\x06\xa9\x21\x40\x36\xb8\xa1\x5b"
+                         "\x51\x2e\x03\xd5\x34\x12\x00\x06",
+               .klen   = 16,
+               .iv     = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30"
+                         "\xb4\x22\xda\x80\x2c\x9f\xac\x41",
+               .input  = "Single block msg",
+               .ilen   = 16,
+               .result = "\xea\x32\x12\x76\x3b\x50\x10\xe7"
+                         "\x18\xf6\xfd\x5d\xf6\x8f\x13\x51",
+               .rlen   = 16,
+       }, {
+               .key    = "\xc2\x86\x69\x6d\x88\x7c\x9a\xa0"
+                         "\x61\x1b\xbb\x3e\x20\x25\xa4\x5a",
+               .klen   = 16,
+               .iv     = "\x56\x2e\x17\x99\x6d\x09\x3d\x28"
+                         "\xdd\xb3\xba\x69\x5a\x2e\x6f\x58",
+               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .ilen   = 32,
+               .result = "\xa5\xdf\x6e\x50\xda\x70\x6c\x01"
+                         "\x4a\xab\xf3\xf2\xd6\xfc\x6c\xfd"
+                         "\x19\xb4\x3e\x57\x1c\x02\x5e\xa0"
+                         "\x15\x78\xe0\x5e\xf2\xcb\x87\x16",
+               .rlen   = 32,
+       },
+};
+
+static struct cipher_testvec camellia_cbc_dec_tv_template[] = {
+       {
+               .key    = "\x06\xa9\x21\x40\x36\xb8\xa1\x5b"
+                         "\x51\x2e\x03\xd5\x34\x12\x00\x06",
+               .klen   = 16,
+               .iv     = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30"
+                         "\xb4\x22\xda\x80\x2c\x9f\xac\x41",
+               .input  = "\xea\x32\x12\x76\x3b\x50\x10\xe7"
+                         "\x18\xf6\xfd\x5d\xf6\x8f\x13\x51",
+               .ilen   = 16,
+               .result = "Single block msg",
+               .rlen   = 16,
+       }, {
+               .key    = "\xc2\x86\x69\x6d\x88\x7c\x9a\xa0"
+                         "\x61\x1b\xbb\x3e\x20\x25\xa4\x5a",
+               .klen   = 16,
+               .iv     = "\x56\x2e\x17\x99\x6d\x09\x3d\x28"
+                         "\xdd\xb3\xba\x69\x5a\x2e\x6f\x58",
+               .input = "\xa5\xdf\x6e\x50\xda\x70\x6c\x01"
+                         "\x4a\xab\xf3\xf2\xd6\xfc\x6c\xfd"
+                         "\x19\xb4\x3e\x57\x1c\x02\x5e\xa0"
+                         "\x15\x78\xe0\x5e\xf2\xcb\x87\x16",
+               .ilen   = 32,
+               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                         "\x10\x11\x12\x13\x14\x15\x16\x17"
+                         "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .rlen   = 32,
+       },
+};
+
+/*
+ * SEED test vectors
+ */
+#define SEED_ENC_TEST_VECTORS  4
+#define SEED_DEC_TEST_VECTORS  4
+
+static struct cipher_testvec seed_enc_tv_template[] = {
+       {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .input  = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .ilen   = 16,
+               .result = "\x5e\xba\xc6\xe0\x05\x4e\x16\x68"
+                         "\x19\xaf\xf1\xcc\x6d\x34\x6c\xdb",
+               .rlen   = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .klen   = 16,
+               .input  = zeroed_string,
+               .ilen   = 16,
+               .result = "\xc1\x1f\x22\xf2\x01\x40\x50\x50"
+                         "\x84\x48\x35\x97\xe4\x37\x0f\x43",
+               .rlen   = 16,
+       }, {
+               .key    = "\x47\x06\x48\x08\x51\xe6\x1b\xe8"
+                         "\x5d\x74\xbf\xb3\xfd\x95\x61\x85",
+               .klen   = 16,
+               .input  = "\x83\xa2\xf8\xa2\x88\x64\x1f\xb9"
+                         "\xa4\xe9\xa5\xcc\x2f\x13\x1c\x7d",
+               .ilen   = 16,
+               .result = "\xee\x54\xd1\x3e\xbc\xae\x70\x6d"
+                         "\x22\x6b\xc3\x14\x2c\xd4\x0d\x4a",
+               .rlen   = 16,
+       }, {
+               .key    = "\x28\xdb\xc3\xbc\x49\xff\xd8\x7d"
+                         "\xcf\xa5\x09\xb1\x1d\x42\x2b\xe7",
+               .klen   = 16,
+               .input  = "\xb4\x1e\x6b\xe2\xeb\xa8\x4a\x14"
+                         "\x8e\x2e\xed\x84\x59\x3c\x5e\xc7",
+               .ilen   = 16,
+               .result = "\x9b\x9b\x7b\xfc\xd1\x81\x3c\xb9"
+                         "\x5d\x0b\x36\x18\xf4\x0f\x51\x22",
+               .rlen   = 16,
+       }
+};
+
+static struct cipher_testvec seed_dec_tv_template[] = {
+       {
+               .key    = zeroed_string,
+               .klen   = 16,
+               .input  = "\x5e\xba\xc6\xe0\x05\x4e\x16\x68"
+                         "\x19\xaf\xf1\xcc\x6d\x34\x6c\xdb",
+               .ilen   = 16,
+               .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .rlen   = 16,
+       }, {
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .klen   = 16,
+               .input  = "\xc1\x1f\x22\xf2\x01\x40\x50\x50"
+                         "\x84\x48\x35\x97\xe4\x37\x0f\x43",
+               .ilen   = 16,
+               .result = zeroed_string,
+               .rlen   = 16,
+       }, {
+               .key    = "\x47\x06\x48\x08\x51\xe6\x1b\xe8"
+                         "\x5d\x74\xbf\xb3\xfd\x95\x61\x85",
+               .klen   = 16,
+               .input  = "\xee\x54\xd1\x3e\xbc\xae\x70\x6d"
+                         "\x22\x6b\xc3\x14\x2c\xd4\x0d\x4a",
+               .ilen   = 16,
+               .result = "\x83\xa2\xf8\xa2\x88\x64\x1f\xb9"
+                         "\xa4\xe9\xa5\xcc\x2f\x13\x1c\x7d",
+               .rlen   = 16,
+       }, {
+               .key    = "\x28\xdb\xc3\xbc\x49\xff\xd8\x7d"
+                         "\xcf\xa5\x09\xb1\x1d\x42\x2b\xe7",
+               .klen   = 16,
+               .input  = "\x9b\x9b\x7b\xfc\xd1\x81\x3c\xb9"
+                         "\x5d\x0b\x36\x18\xf4\x0f\x51\x22",
+               .ilen   = 16,
+               .result = "\xb4\x1e\x6b\xe2\xeb\xa8\x4a\x14"
+                         "\x8e\x2e\xed\x84\x59\x3c\x5e\xc7",
+               .rlen   = 16,
+       }
+};
+
+#define SALSA20_STREAM_ENC_TEST_VECTORS 5
+static struct cipher_testvec salsa20_stream_enc_tv_template[] = {
+       /*
+       * Testvectors from verified.test-vectors submitted to ECRYPT.
+       * They are truncated to size 39, 64, 111, 129 to test a variety
+       * of input length.
+       */
+       { /* Set 3, vector 0 */
+               .key    = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                       "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F",
+               .klen   = 16,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00",
+               .ilen   = 39,
+               .result = "\x2D\xD5\xC3\xF7\xBA\x2B\x20\xF7"
+                        "\x68\x02\x41\x0C\x68\x86\x88\x89"
+                        "\x5A\xD8\xC1\xBD\x4E\xA6\xC9\xB1"
+                        "\x40\xFB\x9B\x90\xE2\x10\x49\xBF"
+                        "\x58\x3F\x52\x79\x70\xEB\xC1",
+               .rlen   = 39,
+       }, { /* Set 5, vector 0 */
+               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 16,
+               .iv     = "\x80\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .ilen   = 64,
+               .result = "\xB6\x6C\x1E\x44\x46\xDD\x95\x57"
+                        "\xE5\x78\xE2\x23\xB0\xB7\x68\x01"
+                        "\x7B\x23\xB2\x67\xBB\x02\x34\xAE"
+                        "\x46\x26\xBF\x44\x3F\x21\x97\x76"
+                        "\x43\x6F\xB1\x9F\xD0\xE8\x86\x6F"
+                        "\xCD\x0D\xE9\xA9\x53\x8F\x4A\x09"
+                        "\xCA\x9A\xC0\x73\x2E\x30\xBC\xF9"
+                        "\x8E\x4F\x13\xE4\xB9\xE2\x01\xD9",
+               .rlen   = 64,
+       }, { /* Set 3, vector 27 */
+               .key    = "\x1B\x1C\x1D\x1E\x1F\x20\x21\x22"
+                       "\x23\x24\x25\x26\x27\x28\x29\x2A"
+                       "\x2B\x2C\x2D\x2E\x2F\x30\x31\x32"
+                       "\x33\x34\x35\x36\x37\x38\x39\x3A",
+               .klen   = 32,
+               .iv     = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00",
+               .ilen   = 111,
+               .result = "\xAE\x39\x50\x8E\xAC\x9A\xEC\xE7"
+                        "\xBF\x97\xBB\x20\xB9\xDE\xE4\x1F"
+                        "\x87\xD9\x47\xF8\x28\x91\x35\x98"
+                        "\xDB\x72\xCC\x23\x29\x48\x56\x5E"
+                        "\x83\x7E\x0B\xF3\x7D\x5D\x38\x7B"
+                        "\x2D\x71\x02\xB4\x3B\xB5\xD8\x23"
+                        "\xB0\x4A\xDF\x3C\xEC\xB6\xD9\x3B"
+                        "\x9B\xA7\x52\xBE\xC5\xD4\x50\x59"
+                        "\x15\x14\xB4\x0E\x40\xE6\x53\xD1"
+                        "\x83\x9C\x5B\xA0\x92\x29\x6B\x5E"
+                        "\x96\x5B\x1E\x2F\xD3\xAC\xC1\x92"
+                        "\xB1\x41\x3F\x19\x2F\xC4\x3B\xC6"
+                        "\x95\x46\x45\x54\xE9\x75\x03\x08"
+                        "\x44\xAF\xE5\x8A\x81\x12\x09",
+               .rlen   = 111,
+       }, { /* Set 5, vector 27 */
+               .key    = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .klen   = 32,
+               .iv     = "\x00\x00\x00\x10\x00\x00\x00\x00",
+               .input  = "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00",
+               .ilen   = 129,
+               .result = "\xD2\xDB\x1A\x5C\xF1\xC1\xAC\xDB"
+                        "\xE8\x1A\x7A\x43\x40\xEF\x53\x43"
+                        "\x5E\x7F\x4B\x1A\x50\x52\x3F\x8D"
+                        "\x28\x3D\xCF\x85\x1D\x69\x6E\x60"
+                        "\xF2\xDE\x74\x56\x18\x1B\x84\x10"
+                        "\xD4\x62\xBA\x60\x50\xF0\x61\xF2"
+                        "\x1C\x78\x7F\xC1\x24\x34\xAF\x58"
+                        "\xBF\x2C\x59\xCA\x90\x77\xF3\xB0"
+                        "\x5B\x4A\xDF\x89\xCE\x2C\x2F\xFC"
+                        "\x67\xF0\xE3\x45\xE8\xB3\xB3\x75"
+                        "\xA0\x95\x71\xA1\x29\x39\x94\xCA"
+                        "\x45\x2F\xBD\xCB\x10\xB6\xBE\x9F"
+                        "\x8E\xF9\xB2\x01\x0A\x5A\x0A\xB7"
+                        "\x6B\x9D\x70\x8E\x4B\xD6\x2F\xCD"
+                        "\x2E\x40\x48\x75\xE9\xE2\x21\x45"
+                        "\x0B\xC9\xB6\xB5\x66\xBC\x9A\x59"
+                        "\x5A",
+               .rlen   = 129,
+       }, { /* large test vector generated using Crypto++ */
+               .key =  "\x00\x01\x02\x03\x04\x05\x06\x07"
+                       "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                       "\x10\x11\x12\x13\x14\x15\x16\x17"
+                       "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+               .klen = 32,
+               .iv =   "\x00\x00\x00\x00\x00\x00\x00\x00"
+                       "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .input =
+                       "\x00\x01\x02\x03\x04\x05\x06\x07"
+                       "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+                       "\x10\x11\x12\x13\x14\x15\x16\x17"
+                       "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+                       "\x20\x21\x22\x23\x24\x25\x26\x27"
+                       "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+                       "\x30\x31\x32\x33\x34\x35\x36\x37"
+                       "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+                       "\x40\x41\x42\x43\x44\x45\x46\x47"
+                       "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+                       "\x50\x51\x52\x53\x54\x55\x56\x57"
+                       "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+                       "\x60\x61\x62\x63\x64\x65\x66\x67"
+                       "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+                       "\x70\x71\x72\x73\x74\x75\x76\x77"
+                       "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+                       "\x80\x81\x82\x83\x84\x85\x86\x87"
+                       "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+                       "\x90\x91\x92\x93\x94\x95\x96\x97"
+                       "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+                       "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+                       "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+                       "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+                       "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+                       "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+                       "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+                       "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+                       "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+                       "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+                       "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+                       "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+                       "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
+                       "\x00\x03\x06\x09\x0c\x0f\x12\x15"
+                       "\x18\x1b\x1e\x21\x24\x27\x2a\x2d"
+                       "\x30\x33\x36\x39\x3c\x3f\x42\x45"
+                       "\x48\x4b\x4e\x51\x54\x57\x5a\x5d"
+                       "\x60\x63\x66\x69\x6c\x6f\x72\x75"
+                       "\x78\x7b\x7e\x81\x84\x87\x8a\x8d"
+                       "\x90\x93\x96\x99\x9c\x9f\xa2\xa5"
+                       "\xa8\xab\xae\xb1\xb4\xb7\xba\xbd"
+                       "\xc0\xc3\xc6\xc9\xcc\xcf\xd2\xd5"
+                       "\xd8\xdb\xde\xe1\xe4\xe7\xea\xed"
+                       "\xf0\xf3\xf6\xf9\xfc\xff\x02\x05"
+                       "\x08\x0b\x0e\x11\x14\x17\x1a\x1d"
+                       "\x20\x23\x26\x29\x2c\x2f\x32\x35"
+                       "\x38\x3b\x3e\x41\x44\x47\x4a\x4d"
+                       "\x50\x53\x56\x59\x5c\x5f\x62\x65"
+                       "\x68\x6b\x6e\x71\x74\x77\x7a\x7d"
+                       "\x80\x83\x86\x89\x8c\x8f\x92\x95"
+                       "\x98\x9b\x9e\xa1\xa4\xa7\xaa\xad"
+                       "\xb0\xb3\xb6\xb9\xbc\xbf\xc2\xc5"
+                       "\xc8\xcb\xce\xd1\xd4\xd7\xda\xdd"
+                       "\xe0\xe3\xe6\xe9\xec\xef\xf2\xf5"
+                       "\xf8\xfb\xfe\x01\x04\x07\x0a\x0d"
+                       "\x10\x13\x16\x19\x1c\x1f\x22\x25"
+                       "\x28\x2b\x2e\x31\x34\x37\x3a\x3d"
+                       "\x40\x43\x46\x49\x4c\x4f\x52\x55"
+                       "\x58\x5b\x5e\x61\x64\x67\x6a\x6d"
+                       "\x70\x73\x76\x79\x7c\x7f\x82\x85"
+                       "\x88\x8b\x8e\x91\x94\x97\x9a\x9d"
+                       "\xa0\xa3\xa6\xa9\xac\xaf\xb2\xb5"
+                       "\xb8\xbb\xbe\xc1\xc4\xc7\xca\xcd"
+                       "\xd0\xd3\xd6\xd9\xdc\xdf\xe2\xe5"
+                       "\xe8\xeb\xee\xf1\xf4\xf7\xfa\xfd"
+                       "\x00\x05\x0a\x0f\x14\x19\x1e\x23"
+                       "\x28\x2d\x32\x37\x3c\x41\x46\x4b"
+                       "\x50\x55\x5a\x5f\x64\x69\x6e\x73"
+                       "\x78\x7d\x82\x87\x8c\x91\x96\x9b"
+                       "\xa0\xa5\xaa\xaf\xb4\xb9\xbe\xc3"
+                       "\xc8\xcd\xd2\xd7\xdc\xe1\xe6\xeb"
+                       "\xf0\xf5\xfa\xff\x04\x09\x0e\x13"
+                       "\x18\x1d\x22\x27\x2c\x31\x36\x3b"
+                       "\x40\x45\x4a\x4f\x54\x59\x5e\x63"
+                       "\x68\x6d\x72\x77\x7c\x81\x86\x8b"
+                       "\x90\x95\x9a\x9f\xa4\xa9\xae\xb3"
+                       "\xb8\xbd\xc2\xc7\xcc\xd1\xd6\xdb"
+                       "\xe0\xe5\xea\xef\xf4\xf9\xfe\x03"
+                       "\x08\x0d\x12\x17\x1c\x21\x26\x2b"
+                       "\x30\x35\x3a\x3f\x44\x49\x4e\x53"
+                       "\x58\x5d\x62\x67\x6c\x71\x76\x7b"
+                       "\x80\x85\x8a\x8f\x94\x99\x9e\xa3"
+                       "\xa8\xad\xb2\xb7\xbc\xc1\xc6\xcb"
+                       "\xd0\xd5\xda\xdf\xe4\xe9\xee\xf3"
+                       "\xf8\xfd\x02\x07\x0c\x11\x16\x1b"
+                       "\x20\x25\x2a\x2f\x34\x39\x3e\x43"
+                       "\x48\x4d\x52\x57\x5c\x61\x66\x6b"
+                       "\x70\x75\x7a\x7f\x84\x89\x8e\x93"
+                       "\x98\x9d\xa2\xa7\xac\xb1\xb6\xbb"
+                       "\xc0\xc5\xca\xcf\xd4\xd9\xde\xe3"
+                       "\xe8\xed\xf2\xf7\xfc\x01\x06\x0b"
+                       "\x10\x15\x1a\x1f\x24\x29\x2e\x33"
+                       "\x38\x3d\x42\x47\x4c\x51\x56\x5b"
+                       "\x60\x65\x6a\x6f\x74\x79\x7e\x83"
+                       "\x88\x8d\x92\x97\x9c\xa1\xa6\xab"
+                       "\xb0\xb5\xba\xbf\xc4\xc9\xce\xd3"
+                       "\xd8\xdd\xe2\xe7\xec\xf1\xf6\xfb"
+                       "\x00\x07\x0e\x15\x1c\x23\x2a\x31"
+                       "\x38\x3f\x46\x4d\x54\x5b\x62\x69"
+                       "\x70\x77\x7e\x85\x8c\x93\x9a\xa1"
+                       "\xa8\xaf\xb6\xbd\xc4\xcb\xd2\xd9"
+                       "\xe0\xe7\xee\xf5\xfc\x03\x0a\x11"
+                       "\x18\x1f\x26\x2d\x34\x3b\x42\x49"
+                       "\x50\x57\x5e\x65\x6c\x73\x7a\x81"
+                       "\x88\x8f\x96\x9d\xa4\xab\xb2\xb9"
+                       "\xc0\xc7\xce\xd5\xdc\xe3\xea\xf1"
+                       "\xf8\xff\x06\x0d\x14\x1b\x22\x29"
+                       "\x30\x37\x3e\x45\x4c\x53\x5a\x61"
+                       "\x68\x6f\x76\x7d\x84\x8b\x92\x99"
+                       "\xa0\xa7\xae\xb5\xbc\xc3\xca\xd1"
+                       "\xd8\xdf\xe6\xed\xf4\xfb\x02\x09"
+                       "\x10\x17\x1e\x25\x2c\x33\x3a\x41"
+                       "\x48\x4f\x56\x5d\x64\x6b\x72\x79"
+                       "\x80\x87\x8e\x95\x9c\xa3\xaa\xb1"
+                       "\xb8\xbf\xc6\xcd\xd4\xdb\xe2\xe9"
+                       "\xf0\xf7\xfe\x05\x0c\x13\x1a\x21"
+                       "\x28\x2f\x36\x3d\x44\x4b\x52\x59"
+                       "\x60\x67\x6e\x75\x7c\x83\x8a\x91"
+                       "\x98\x9f\xa6\xad\xb4\xbb\xc2\xc9"
+                       "\xd0\xd7\xde\xe5\xec\xf3\xfa\x01"
+                       "\x08\x0f\x16\x1d\x24\x2b\x32\x39"
+                       "\x40\x47\x4e\x55\x5c\x63\x6a\x71"
+                       "\x78\x7f\x86\x8d\x94\x9b\xa2\xa9"
+                       "\xb0\xb7\xbe\xc5\xcc\xd3\xda\xe1"
+                       "\xe8\xef\xf6\xfd\x04\x0b\x12\x19"
+                       "\x20\x27\x2e\x35\x3c\x43\x4a\x51"
+                       "\x58\x5f\x66\x6d\x74\x7b\x82\x89"
+                       "\x90\x97\x9e\xa5\xac\xb3\xba\xc1"
+                       "\xc8\xcf\xd6\xdd\xe4\xeb\xf2\xf9"
+                       "\x00\x09\x12\x1b\x24\x2d\x36\x3f"
+                       "\x48\x51\x5a\x63\x6c\x75\x7e\x87"
+                       "\x90\x99\xa2\xab\xb4\xbd\xc6\xcf"
+                       "\xd8\xe1\xea\xf3\xfc\x05\x0e\x17"
+                       "\x20\x29\x32\x3b\x44\x4d\x56\x5f"
+                       "\x68\x71\x7a\x83\x8c\x95\x9e\xa7"
+                       "\xb0\xb9\xc2\xcb\xd4\xdd\xe6\xef"
+                       "\xf8\x01\x0a\x13\x1c\x25\x2e\x37"
+                       "\x40\x49\x52\x5b\x64\x6d\x76\x7f"
+                       "\x88\x91\x9a\xa3\xac\xb5\xbe\xc7"
+                       "\xd0\xd9\xe2\xeb\xf4\xfd\x06\x0f"
+                       "\x18\x21\x2a\x33\x3c\x45\x4e\x57"
+                       "\x60\x69\x72\x7b\x84\x8d\x96\x9f"
+                       "\xa8\xb1\xba\xc3\xcc\xd5\xde\xe7"
+                       "\xf0\xf9\x02\x0b\x14\x1d\x26\x2f"
+                       "\x38\x41\x4a\x53\x5c\x65\x6e\x77"
+                       "\x80\x89\x92\x9b\xa4\xad\xb6\xbf"
+                       "\xc8\xd1\xda\xe3\xec\xf5\xfe\x07"
+                       "\x10\x19\x22\x2b\x34\x3d\x46\x4f"
+                       "\x58\x61\x6a\x73\x7c\x85\x8e\x97"
+                       "\xa0\xa9\xb2\xbb\xc4\xcd\xd6\xdf"
+                       "\xe8\xf1\xfa\x03\x0c\x15\x1e\x27"
+                       "\x30\x39\x42\x4b\x54\x5d\x66\x6f"
+                       "\x78\x81\x8a\x93\x9c\xa5\xae\xb7"
+                       "\xc0\xc9\xd2\xdb\xe4\xed\xf6\xff"
+                       "\x08\x11\x1a\x23\x2c\x35\x3e\x47"
+                       "\x50\x59\x62\x6b\x74\x7d\x86\x8f"
+                       "\x98\xa1\xaa\xb3\xbc\xc5\xce\xd7"
+                       "\xe0\xe9\xf2\xfb\x04\x0d\x16\x1f"
+                       "\x28\x31\x3a\x43\x4c\x55\x5e\x67"
+                       "\x70\x79\x82\x8b\x94\x9d\xa6\xaf"
+                       "\xb8\xc1\xca\xd3\xdc\xe5\xee\xf7"
+                       "\x00\x0b\x16\x21\x2c\x37\x42\x4d"
+                       "\x58\x63\x6e\x79\x84\x8f\x9a\xa5"
+                       "\xb0\xbb\xc6\xd1\xdc\xe7\xf2\xfd"
+                       "\x08\x13\x1e\x29\x34\x3f\x4a\x55"
+                       "\x60\x6b\x76\x81\x8c\x97\xa2\xad"
+                       "\xb8\xc3\xce\xd9\xe4\xef\xfa\x05"
+                       "\x10\x1b\x26\x31\x3c\x47\x52\x5d"
+                       "\x68\x73\x7e\x89\x94\x9f\xaa\xb5"
+                       "\xc0\xcb\xd6\xe1\xec\xf7\x02\x0d"
+                       "\x18\x23\x2e\x39\x44\x4f\x5a\x65"
+                       "\x70\x7b\x86\x91\x9c\xa7\xb2\xbd"
+                       "\xc8\xd3\xde\xe9\xf4\xff\x0a\x15"
+                       "\x20\x2b\x36\x41\x4c\x57\x62\x6d"
+                       "\x78\x83\x8e\x99\xa4\xaf\xba\xc5"
+                       "\xd0\xdb\xe6\xf1\xfc\x07\x12\x1d"
+                       "\x28\x33\x3e\x49\x54\x5f\x6a\x75"
+                       "\x80\x8b\x96\xa1\xac\xb7\xc2\xcd"
+                       "\xd8\xe3\xee\xf9\x04\x0f\x1a\x25"
+                       "\x30\x3b\x46\x51\x5c\x67\x72\x7d"
+                       "\x88\x93\x9e\xa9\xb4\xbf\xca\xd5"
+                       "\xe0\xeb\xf6\x01\x0c\x17\x22\x2d"
+                       "\x38\x43\x4e\x59\x64\x6f\x7a\x85"
+                       "\x90\x9b\xa6\xb1\xbc\xc7\xd2\xdd"
+                       "\xe8\xf3\xfe\x09\x14\x1f\x2a\x35"
+                       "\x40\x4b\x56\x61\x6c\x77\x82\x8d"
+                       "\x98\xa3\xae\xb9\xc4\xcf\xda\xe5"
+                       "\xf0\xfb\x06\x11\x1c\x27\x32\x3d"
+                       "\x48\x53\x5e\x69\x74\x7f\x8a\x95"
+                       "\xa0\xab\xb6\xc1\xcc\xd7\xe2\xed"
+                       "\xf8\x03\x0e\x19\x24\x2f\x3a\x45"
+                       "\x50\x5b\x66\x71\x7c\x87\x92\x9d"
+                       "\xa8\xb3\xbe\xc9\xd4\xdf\xea\xf5"
+                       "\x00\x0d\x1a\x27\x34\x41\x4e\x5b"
+                       "\x68\x75\x82\x8f\x9c\xa9\xb6\xc3"
+                       "\xd0\xdd\xea\xf7\x04\x11\x1e\x2b"
+                       "\x38\x45\x52\x5f\x6c\x79\x86\x93"
+                       "\xa0\xad\xba\xc7\xd4\xe1\xee\xfb"
+                       "\x08\x15\x22\x2f\x3c\x49\x56\x63"
+                       "\x70\x7d\x8a\x97\xa4\xb1\xbe\xcb"
+                       "\xd8\xe5\xf2\xff\x0c\x19\x26\x33"
+                       "\x40\x4d\x5a\x67\x74\x81\x8e\x9b"
+                       "\xa8\xb5\xc2\xcf\xdc\xe9\xf6\x03"
+                       "\x10\x1d\x2a\x37\x44\x51\x5e\x6b"
+                       "\x78\x85\x92\x9f\xac\xb9\xc6\xd3"
+                       "\xe0\xed\xfa\x07\x14\x21\x2e\x3b"
+                       "\x48\x55\x62\x6f\x7c\x89\x96\xa3"
+                       "\xb0\xbd\xca\xd7\xe4\xf1\xfe\x0b"
+                       "\x18\x25\x32\x3f\x4c\x59\x66\x73"
+                       "\x80\x8d\x9a\xa7\xb4\xc1\xce\xdb"
+                       "\xe8\xf5\x02\x0f\x1c\x29\x36\x43"
+                       "\x50\x5d\x6a\x77\x84\x91\x9e\xab"
+                       "\xb8\xc5\xd2\xdf\xec\xf9\x06\x13"
+                       "\x20\x2d\x3a\x47\x54\x61\x6e\x7b"
+                       "\x88\x95\xa2\xaf\xbc\xc9\xd6\xe3"
+                       "\xf0\xfd\x0a\x17\x24\x31\x3e\x4b"
+                       "\x58\x65\x72\x7f\x8c\x99\xa6\xb3"
+                       "\xc0\xcd\xda\xe7\xf4\x01\x0e\x1b"
+                       "\x28\x35\x42\x4f\x5c\x69\x76\x83"
+                       "\x90\x9d\xaa\xb7\xc4\xd1\xde\xeb"
+                       "\xf8\x05\x12\x1f\x2c\x39\x46\x53"
+                       "\x60\x6d\x7a\x87\x94\xa1\xae\xbb"
+                       "\xc8\xd5\xe2\xef\xfc\x09\x16\x23"
+                       "\x30\x3d\x4a\x57\x64\x71\x7e\x8b"
+                       "\x98\xa5\xb2\xbf\xcc\xd9\xe6\xf3"
+                       "\x00\x0f\x1e\x2d\x3c\x4b\x5a\x69"
+                       "\x78\x87\x96\xa5\xb4\xc3\xd2\xe1"
+                       "\xf0\xff\x0e\x1d\x2c\x3b\x4a\x59"
+                       "\x68\x77\x86\x95\xa4\xb3\xc2\xd1"
+                       "\xe0\xef\xfe\x0d\x1c\x2b\x3a\x49"
+                       "\x58\x67\x76\x85\x94\xa3\xb2\xc1"
+                       "\xd0\xdf\xee\xfd\x0c\x1b\x2a\x39"
+                       "\x48\x57\x66\x75\x84\x93\xa2\xb1"
+                       "\xc0\xcf\xde\xed\xfc\x0b\x1a\x29"
+                       "\x38\x47\x56\x65\x74\x83\x92\xa1"
+                       "\xb0\xbf\xce\xdd\xec\xfb\x0a\x19"
+                       "\x28\x37\x46\x55\x64\x73\x82\x91"
+                       "\xa0\xaf\xbe\xcd\xdc\xeb\xfa\x09"
+                       "\x18\x27\x36\x45\x54\x63\x72\x81"
+                       "\x90\x9f\xae\xbd\xcc\xdb\xea\xf9"
+                       "\x08\x17\x26\x35\x44\x53\x62\x71"
+                       "\x80\x8f\x9e\xad\xbc\xcb\xda\xe9"
+                       "\xf8\x07\x16\x25\x34\x43\x52\x61"
+                       "\x70\x7f\x8e\x9d\xac\xbb\xca\xd9"
+                       "\xe8\xf7\x06\x15\x24\x33\x42\x51"
+                       "\x60\x6f\x7e\x8d\x9c\xab\xba\xc9"
+                       "\xd8\xe7\xf6\x05\x14\x23\x32\x41"
+                       "\x50\x5f\x6e\x7d\x8c\x9b\xaa\xb9"
+                       "\xc8\xd7\xe6\xf5\x04\x13\x22\x31"
+                       "\x40\x4f\x5e\x6d\x7c\x8b\x9a\xa9"
+                       "\xb8\xc7\xd6\xe5\xf4\x03\x12\x21"
+                       "\x30\x3f\x4e\x5d\x6c\x7b\x8a\x99"
+                       "\xa8\xb7\xc6\xd5\xe4\xf3\x02\x11"
+                       "\x20\x2f\x3e\x4d\x5c\x6b\x7a\x89"
+                       "\x98\xa7\xb6\xc5\xd4\xe3\xf2\x01"
+                       "\x10\x1f\x2e\x3d\x4c\x5b\x6a\x79"
+                       "\x88\x97\xa6\xb5\xc4\xd3\xe2\xf1"
+                       "\x00\x11\x22\x33\x44\x55\x66\x77"
+                       "\x88\x99\xaa\xbb\xcc\xdd\xee\xff"
+                       "\x10\x21\x32\x43\x54\x65\x76\x87"
+                       "\x98\xa9\xba\xcb\xdc\xed\xfe\x0f"
+                       "\x20\x31\x42\x53\x64\x75\x86\x97"
+                       "\xa8\xb9\xca\xdb\xec\xfd\x0e\x1f"
+                       "\x30\x41\x52\x63\x74\x85\x96\xa7"
+                       "\xb8\xc9\xda\xeb\xfc\x0d\x1e\x2f"
+                       "\x40\x51\x62\x73\x84\x95\xa6\xb7"
+                       "\xc8\xd9\xea\xfb\x0c\x1d\x2e\x3f"
+                       "\x50\x61\x72\x83\x94\xa5\xb6\xc7"
+                       "\xd8\xe9\xfa\x0b\x1c\x2d\x3e\x4f"
+                       "\x60\x71\x82\x93\xa4\xb5\xc6\xd7"
+                       "\xe8\xf9\x0a\x1b\x2c\x3d\x4e\x5f"
+                       "\x70\x81\x92\xa3\xb4\xc5\xd6\xe7"
+                       "\xf8\x09\x1a\x2b\x3c\x4d\x5e\x6f"
+                       "\x80\x91\xa2\xb3\xc4\xd5\xe6\xf7"
+                       "\x08\x19\x2a\x3b\x4c\x5d\x6e\x7f"
+                       "\x90\xa1\xb2\xc3\xd4\xe5\xf6\x07"
+                       "\x18\x29\x3a\x4b\x5c\x6d\x7e\x8f"
+                       "\xa0\xb1\xc2\xd3\xe4\xf5\x06\x17"
+                       "\x28\x39\x4a\x5b\x6c\x7d\x8e\x9f"
+                       "\xb0\xc1\xd2\xe3\xf4\x05\x16\x27"
+                       "\x38\x49\x5a\x6b\x7c\x8d\x9e\xaf"
+                       "\xc0\xd1\xe2\xf3\x04\x15\x26\x37"
+                       "\x48\x59\x6a\x7b\x8c\x9d\xae\xbf"
+                       "\xd0\xe1\xf2\x03\x14\x25\x36\x47"
+                       "\x58\x69\x7a\x8b\x9c\xad\xbe\xcf"
+                       "\xe0\xf1\x02\x13\x24\x35\x46\x57"
+                       "\x68\x79\x8a\x9b\xac\xbd\xce\xdf"
+                       "\xf0\x01\x12\x23\x34\x45\x56\x67"
+                       "\x78\x89\x9a\xab\xbc\xcd\xde\xef"
+                       "\x00\x13\x26\x39\x4c\x5f\x72\x85"
+                       "\x98\xab\xbe\xd1\xe4\xf7\x0a\x1d"
+                       "\x30\x43\x56\x69\x7c\x8f\xa2\xb5"
+                       "\xc8\xdb\xee\x01\x14\x27\x3a\x4d"
+                       "\x60\x73\x86\x99\xac\xbf\xd2\xe5"
+                       "\xf8\x0b\x1e\x31\x44\x57\x6a\x7d"
+                       "\x90\xa3\xb6\xc9\xdc\xef\x02\x15"
+                       "\x28\x3b\x4e\x61\x74\x87\x9a\xad"
+                       "\xc0\xd3\xe6\xf9\x0c\x1f\x32\x45"
+                       "\x58\x6b\x7e\x91\xa4\xb7\xca\xdd"
+                       "\xf0\x03\x16\x29\x3c\x4f\x62\x75"
+                       "\x88\x9b\xae\xc1\xd4\xe7\xfa\x0d"
+                       "\x20\x33\x46\x59\x6c\x7f\x92\xa5"
+                       "\xb8\xcb\xde\xf1\x04\x17\x2a\x3d"
+                       "\x50\x63\x76\x89\x9c\xaf\xc2\xd5"
+                       "\xe8\xfb\x0e\x21\x34\x47\x5a\x6d"
+                       "\x80\x93\xa6\xb9\xcc\xdf\xf2\x05"
+                       "\x18\x2b\x3e\x51\x64\x77\x8a\x9d"
+                       "\xb0\xc3\xd6\xe9\xfc\x0f\x22\x35"
+                       "\x48\x5b\x6e\x81\x94\xa7\xba\xcd"
+                       "\xe0\xf3\x06\x19\x2c\x3f\x52\x65"
+                       "\x78\x8b\x9e\xb1\xc4\xd7\xea\xfd"
+                       "\x10\x23\x36\x49\x5c\x6f\x82\x95"
+                       "\xa8\xbb\xce\xe1\xf4\x07\x1a\x2d"
+                       "\x40\x53\x66\x79\x8c\x9f\xb2\xc5"
+                       "\xd8\xeb\xfe\x11\x24\x37\x4a\x5d"
+                       "\x70\x83\x96\xa9\xbc\xcf\xe2\xf5"
+                       "\x08\x1b\x2e\x41\x54\x67\x7a\x8d"
+                       "\xa0\xb3\xc6\xd9\xec\xff\x12\x25"
+                       "\x38\x4b\x5e\x71\x84\x97\xaa\xbd"
+                       "\xd0\xe3\xf6\x09\x1c\x2f\x42\x55"
+                       "\x68\x7b\x8e\xa1\xb4\xc7\xda\xed"
+                       "\x00\x15\x2a\x3f\x54\x69\x7e\x93"
+                       "\xa8\xbd\xd2\xe7\xfc\x11\x26\x3b"
+                       "\x50\x65\x7a\x8f\xa4\xb9\xce\xe3"
+                       "\xf8\x0d\x22\x37\x4c\x61\x76\x8b"
+                       "\xa0\xb5\xca\xdf\xf4\x09\x1e\x33"
+                       "\x48\x5d\x72\x87\x9c\xb1\xc6\xdb"
+                       "\xf0\x05\x1a\x2f\x44\x59\x6e\x83"
+                       "\x98\xad\xc2\xd7\xec\x01\x16\x2b"
+                       "\x40\x55\x6a\x7f\x94\xa9\xbe\xd3"
+                       "\xe8\xfd\x12\x27\x3c\x51\x66\x7b"
+                       "\x90\xa5\xba\xcf\xe4\xf9\x0e\x23"
+                       "\x38\x4d\x62\x77\x8c\xa1\xb6\xcb"
+                       "\xe0\xf5\x0a\x1f\x34\x49\x5e\x73"
+                       "\x88\x9d\xb2\xc7\xdc\xf1\x06\x1b"
+                       "\x30\x45\x5a\x6f\x84\x99\xae\xc3"
+                       "\xd8\xed\x02\x17\x2c\x41\x56\x6b"
+                       "\x80\x95\xaa\xbf\xd4\xe9\xfe\x13"
+                       "\x28\x3d\x52\x67\x7c\x91\xa6\xbb"
+                       "\xd0\xe5\xfa\x0f\x24\x39\x4e\x63"
+                       "\x78\x8d\xa2\xb7\xcc\xe1\xf6\x0b"
+                       "\x20\x35\x4a\x5f\x74\x89\x9e\xb3"
+                       "\xc8\xdd\xf2\x07\x1c\x31\x46\x5b"
+                       "\x70\x85\x9a\xaf\xc4\xd9\xee\x03"
+                       "\x18\x2d\x42\x57\x6c\x81\x96\xab"
+                       "\xc0\xd5\xea\xff\x14\x29\x3e\x53"
+                       "\x68\x7d\x92\xa7\xbc\xd1\xe6\xfb"
+                       "\x10\x25\x3a\x4f\x64\x79\x8e\xa3"
+                       "\xb8\xcd\xe2\xf7\x0c\x21\x36\x4b"
+                       "\x60\x75\x8a\x9f\xb4\xc9\xde\xf3"
+                       "\x08\x1d\x32\x47\x5c\x71\x86\x9b"
+                       "\xb0\xc5\xda\xef\x04\x19\x2e\x43"
+                       "\x58\x6d\x82\x97\xac\xc1\xd6\xeb"
+                       "\x00\x17\x2e\x45\x5c\x73\x8a\xa1"
+                       "\xb8\xcf\xe6\xfd\x14\x2b\x42\x59"
+                       "\x70\x87\x9e\xb5\xcc\xe3\xfa\x11"
+                       "\x28\x3f\x56\x6d\x84\x9b\xb2\xc9"
+                       "\xe0\xf7\x0e\x25\x3c\x53\x6a\x81"
+                       "\x98\xaf\xc6\xdd\xf4\x0b\x22\x39"
+                       "\x50\x67\x7e\x95\xac\xc3\xda\xf1"
+                       "\x08\x1f\x36\x4d\x64\x7b\x92\xa9"
+                       "\xc0\xd7\xee\x05\x1c\x33\x4a\x61"
+                       "\x78\x8f\xa6\xbd\xd4\xeb\x02\x19"
+                       "\x30\x47\x5e\x75\x8c\xa3\xba\xd1"
+                       "\xe8\xff\x16\x2d\x44\x5b\x72\x89"
+                       "\xa0\xb7\xce\xe5\xfc\x13\x2a\x41"
+                       "\x58\x6f\x86\x9d\xb4\xcb\xe2\xf9"
+                       "\x10\x27\x3e\x55\x6c\x83\x9a\xb1"
+                       "\xc8\xdf\xf6\x0d\x24\x3b\x52\x69"
+                       "\x80\x97\xae\xc5\xdc\xf3\x0a\x21"
+                       "\x38\x4f\x66\x7d\x94\xab\xc2\xd9"
+                       "\xf0\x07\x1e\x35\x4c\x63\x7a\x91"
+                       "\xa8\xbf\xd6\xed\x04\x1b\x32\x49"
+                       "\x60\x77\x8e\xa5\xbc\xd3\xea\x01"
+                       "\x18\x2f\x46\x5d\x74\x8b\xa2\xb9"
+                       "\xd0\xe7\xfe\x15\x2c\x43\x5a\x71"
+                       "\x88\x9f\xb6\xcd\xe4\xfb\x12\x29"
+                       "\x40\x57\x6e\x85\x9c\xb3\xca\xe1"
+                       "\xf8\x0f\x26\x3d\x54\x6b\x82\x99"
+                       "\xb0\xc7\xde\xf5\x0c\x23\x3a\x51"
+                       "\x68\x7f\x96\xad\xc4\xdb\xf2\x09"
+                       "\x20\x37\x4e\x65\x7c\x93\xaa\xc1"
+                       "\xd8\xef\x06\x1d\x34\x4b\x62\x79"
+                       "\x90\xa7\xbe\xd5\xec\x03\x1a\x31"
+                       "\x48\x5f\x76\x8d\xa4\xbb\xd2\xe9"
+                       "\x00\x19\x32\x4b\x64\x7d\x96\xaf"
+                       "\xc8\xe1\xfa\x13\x2c\x45\x5e\x77"
+                       "\x90\xa9\xc2\xdb\xf4\x0d\x26\x3f"
+                       "\x58\x71\x8a\xa3\xbc\xd5\xee\x07"
+                       "\x20\x39\x52\x6b\x84\x9d\xb6\xcf"
+                       "\xe8\x01\x1a\x33\x4c\x65\x7e\x97"
+                       "\xb0\xc9\xe2\xfb\x14\x2d\x46\x5f"
+                       "\x78\x91\xaa\xc3\xdc\xf5\x0e\x27"
+                       "\x40\x59\x72\x8b\xa4\xbd\xd6\xef"
+                       "\x08\x21\x3a\x53\x6c\x85\x9e\xb7"
+                       "\xd0\xe9\x02\x1b\x34\x4d\x66\x7f"
+                       "\x98\xb1\xca\xe3\xfc\x15\x2e\x47"
+                       "\x60\x79\x92\xab\xc4\xdd\xf6\x0f"
+                       "\x28\x41\x5a\x73\x8c\xa5\xbe\xd7"
+                       "\xf0\x09\x22\x3b\x54\x6d\x86\x9f"
+                       "\xb8\xd1\xea\x03\x1c\x35\x4e\x67"
+                       "\x80\x99\xb2\xcb\xe4\xfd\x16\x2f"
+                       "\x48\x61\x7a\x93\xac\xc5\xde\xf7"
+                       "\x10\x29\x42\x5b\x74\x8d\xa6\xbf"
+                       "\xd8\xf1\x0a\x23\x3c\x55\x6e\x87"
+                       "\xa0\xb9\xd2\xeb\x04\x1d\x36\x4f"
+                       "\x68\x81\x9a\xb3\xcc\xe5\xfe\x17"
+                       "\x30\x49\x62\x7b\x94\xad\xc6\xdf"
+                       "\xf8\x11\x2a\x43\x5c\x75\x8e\xa7"
+                       "\xc0\xd9\xf2\x0b\x24\x3d\x56\x6f"
+                       "\x88\xa1\xba\xd3\xec\x05\x1e\x37"
+                       "\x50\x69\x82\x9b\xb4\xcd\xe6\xff"
+                       "\x18\x31\x4a\x63\x7c\x95\xae\xc7"
+                       "\xe0\xf9\x12\x2b\x44\x5d\x76\x8f"
+                       "\xa8\xc1\xda\xf3\x0c\x25\x3e\x57"
+                       "\x70\x89\xa2\xbb\xd4\xed\x06\x1f"
+                       "\x38\x51\x6a\x83\x9c\xb5\xce\xe7"
+                       "\x00\x1b\x36\x51\x6c\x87\xa2\xbd"
+                       "\xd8\xf3\x0e\x29\x44\x5f\x7a\x95"
+                       "\xb0\xcb\xe6\x01\x1c\x37\x52\x6d"
+                       "\x88\xa3\xbe\xd9\xf4\x0f\x2a\x45"
+                       "\x60\x7b\x96\xb1\xcc\xe7\x02\x1d"
+                       "\x38\x53\x6e\x89\xa4\xbf\xda\xf5"
+                       "\x10\x2b\x46\x61\x7c\x97\xb2\xcd"
+                       "\xe8\x03\x1e\x39\x54\x6f\x8a\xa5"
+                       "\xc0\xdb\xf6\x11\x2c\x47\x62\x7d"
+                       "\x98\xb3\xce\xe9\x04\x1f\x3a\x55"
+                       "\x70\x8b\xa6\xc1\xdc\xf7\x12\x2d"
+                       "\x48\x63\x7e\x99\xb4\xcf\xea\x05"
+                       "\x20\x3b\x56\x71\x8c\xa7\xc2\xdd"
+                       "\xf8\x13\x2e\x49\x64\x7f\x9a\xb5"
+                       "\xd0\xeb\x06\x21\x3c\x57\x72\x8d"
+                       "\xa8\xc3\xde\xf9\x14\x2f\x4a\x65"
+                       "\x80\x9b\xb6\xd1\xec\x07\x22\x3d"
+                       "\x58\x73\x8e\xa9\xc4\xdf\xfa\x15"
+                       "\x30\x4b\x66\x81\x9c\xb7\xd2\xed"
+                       "\x08\x23\x3e\x59\x74\x8f\xaa\xc5"
+                       "\xe0\xfb\x16\x31\x4c\x67\x82\x9d"
+                       "\xb8\xd3\xee\x09\x24\x3f\x5a\x75"
+                       "\x90\xab\xc6\xe1\xfc\x17\x32\x4d"
+                       "\x68\x83\x9e\xb9\xd4\xef\x0a\x25"
+                       "\x40\x5b\x76\x91\xac\xc7\xe2\xfd"
+                       "\x18\x33\x4e\x69\x84\x9f\xba\xd5"
+                       "\xf0\x0b\x26\x41\x5c\x77\x92\xad"
+                       "\xc8\xe3\xfe\x19\x34\x4f\x6a\x85"
+                       "\xa0\xbb\xd6\xf1\x0c\x27\x42\x5d"
+                       "\x78\x93\xae\xc9\xe4\xff\x1a\x35"
+                       "\x50\x6b\x86\xa1\xbc\xd7\xf2\x0d"
+                       "\x28\x43\x5e\x79\x94\xaf\xca\xe5"
+                       "\x00\x1d\x3a\x57\x74\x91\xae\xcb"
+                       "\xe8\x05\x22\x3f\x5c\x79\x96\xb3"
+                       "\xd0\xed\x0a\x27\x44\x61\x7e\x9b"
+                       "\xb8\xd5\xf2\x0f\x2c\x49\x66\x83"
+                       "\xa0\xbd\xda\xf7\x14\x31\x4e\x6b"
+                       "\x88\xa5\xc2\xdf\xfc\x19\x36\x53"
+                       "\x70\x8d\xaa\xc7\xe4\x01\x1e\x3b"
+                       "\x58\x75\x92\xaf\xcc\xe9\x06\x23"
+                       "\x40\x5d\x7a\x97\xb4\xd1\xee\x0b"
+                       "\x28\x45\x62\x7f\x9c\xb9\xd6\xf3"
+                       "\x10\x2d\x4a\x67\x84\xa1\xbe\xdb"
+                       "\xf8\x15\x32\x4f\x6c\x89\xa6\xc3"
+                       "\xe0\xfd\x1a\x37\x54\x71\x8e\xab"
+                       "\xc8\xe5\x02\x1f\x3c\x59\x76\x93"
+                       "\xb0\xcd\xea\x07\x24\x41\x5e\x7b"
+                       "\x98\xb5\xd2\xef\x0c\x29\x46\x63"
+                       "\x80\x9d\xba\xd7\xf4\x11\x2e\x4b"
+                       "\x68\x85\xa2\xbf\xdc\xf9\x16\x33"
+                       "\x50\x6d\x8a\xa7\xc4\xe1\xfe\x1b"
+                       "\x38\x55\x72\x8f\xac\xc9\xe6\x03"
+                       "\x20\x3d\x5a\x77\x94\xb1\xce\xeb"
+                       "\x08\x25\x42\x5f\x7c\x99\xb6\xd3"
+                       "\xf0\x0d\x2a\x47\x64\x81\x9e\xbb"
+                       "\xd8\xf5\x12\x2f\x4c\x69\x86\xa3"
+                       "\xc0\xdd\xfa\x17\x34\x51\x6e\x8b"
+                       "\xa8\xc5\xe2\xff\x1c\x39\x56\x73"
+                       "\x90\xad\xca\xe7\x04\x21\x3e\x5b"
+                       "\x78\x95\xb2\xcf\xec\x09\x26\x43"
+                       "\x60\x7d\x9a\xb7\xd4\xf1\x0e\x2b"
+                       "\x48\x65\x82\x9f\xbc\xd9\xf6\x13"
+                       "\x30\x4d\x6a\x87\xa4\xc1\xde\xfb"
+                       "\x18\x35\x52\x6f\x8c\xa9\xc6\xe3"
+                       "\x00\x1f\x3e\x5d\x7c\x9b\xba\xd9"
+                       "\xf8\x17\x36\x55\x74\x93\xb2\xd1"
+                       "\xf0\x0f\x2e\x4d\x6c\x8b\xaa\xc9"
+                       "\xe8\x07\x26\x45\x64\x83\xa2\xc1"
+                       "\xe0\xff\x1e\x3d\x5c\x7b\x9a\xb9"
+                       "\xd8\xf7\x16\x35\x54\x73\x92\xb1"
+                       "\xd0\xef\x0e\x2d\x4c\x6b\x8a\xa9"
+                       "\xc8\xe7\x06\x25\x44\x63\x82\xa1"
+                       "\xc0\xdf\xfe\x1d\x3c\x5b\x7a\x99"
+                       "\xb8\xd7\xf6\x15\x34\x53\x72\x91"
+                       "\xb0\xcf\xee\x0d\x2c\x4b\x6a\x89"
+                       "\xa8\xc7\xe6\x05\x24\x43\x62\x81"
+                       "\xa0\xbf\xde\xfd\x1c\x3b\x5a\x79"
+                       "\x98\xb7\xd6\xf5\x14\x33\x52\x71"
+                       "\x90\xaf\xce\xed\x0c\x2b\x4a\x69"
+                       "\x88\xa7\xc6\xe5\x04\x23\x42\x61"
+                       "\x80\x9f\xbe\xdd\xfc\x1b\x3a\x59"
+                       "\x78\x97\xb6\xd5\xf4\x13\x32\x51"
+                       "\x70\x8f\xae\xcd\xec\x0b\x2a\x49"
+                       "\x68\x87\xa6\xc5\xe4\x03\x22\x41"
+                       "\x60\x7f\x9e\xbd\xdc\xfb\x1a\x39"
+                       "\x58\x77\x96\xb5\xd4\xf3\x12\x31"
+                       "\x50\x6f\x8e\xad\xcc\xeb\x0a\x29"
+                       "\x48\x67\x86\xa5\xc4\xe3\x02\x21"
+                       "\x40\x5f\x7e\x9d\xbc\xdb\xfa\x19"
+                       "\x38\x57\x76\x95\xb4\xd3\xf2\x11"
+                       "\x30\x4f\x6e\x8d\xac\xcb\xea\x09"
+                       "\x28\x47\x66\x85\xa4\xc3\xe2\x01"
+                       "\x20\x3f\x5e\x7d\x9c\xbb\xda\xf9"
+                       "\x18\x37\x56\x75\x94\xb3\xd2\xf1"
+                       "\x10\x2f\x4e\x6d\x8c\xab\xca\xe9"
+                       "\x08\x27\x46\x65\x84\xa3\xc2\xe1"
+                       "\x00\x21\x42\x63",
+               .ilen = 4100,
+               .result =
+                       "\xb5\x81\xf5\x64\x18\x73\xe3\xf0"
+                       "\x4c\x13\xf2\x77\x18\x60\x65\x5e"
+                       "\x29\x01\xce\x98\x55\x53\xf9\x0c"
+                       "\x2a\x08\xd5\x09\xb3\x57\x55\x56"
+                       "\xc5\xe9\x56\x90\xcb\x6a\xa3\xc0"
+                       "\xff\xc4\x79\xb4\xd2\x97\x5d\xc4"
+                       "\x43\xd1\xfe\x94\x7b\x88\x06\x5a"
+                       "\xb2\x9e\x2c\xfc\x44\x03\xb7\x90"
+                       "\xa0\xc1\xba\x6a\x33\xb8\xc7\xb2"
+                       "\x9d\xe1\x12\x4f\xc0\x64\xd4\x01"
+                       "\xfe\x8c\x7a\x66\xf7\xe6\x5a\x91"
+                       "\xbb\xde\x56\x86\xab\x65\x21\x30"
+                       "\x00\x84\x65\x24\xa5\x7d\x85\xb4"
+                       "\xe3\x17\xed\x3a\xb7\x6f\xb4\x0b"
+                       "\x0b\xaf\x15\xae\x5a\x8f\xf2\x0c"
+                       "\x2f\x27\xf4\x09\xd8\xd2\x96\xb7"
+                       "\x71\xf2\xc5\x99\x4d\x7e\x7f\x75"
+                       "\x77\x89\x30\x8b\x59\xdb\xa2\xb2"
+                       "\xa0\xf3\x19\x39\x2b\xc5\x7e\x3f"
+                       "\x4f\xd9\xd3\x56\x28\x97\x44\xdc"
+                       "\xc0\x8b\x77\x24\xd9\x52\xe7\xc5"
+                       "\xaf\xf6\x7d\x59\xb2\x44\x05\x1d"
+                       "\xb1\xb0\x11\xa5\x0f\xec\x33\xe1"
+                       "\x6d\x1b\x4e\x1f\xff\x57\x91\xb4"
+                       "\x5b\x9a\x96\xc5\x53\xbc\xae\x20"
+                       "\x3c\xbb\x14\xe2\xe8\x22\x33\xc1"
+                       "\x5e\x76\x9e\x46\x99\xf6\x2a\x15"
+                       "\xc6\x97\x02\xa0\x66\x43\xd1\xa6"
+                       "\x31\xa6\x9f\xfb\xf4\xd3\x69\xe5"
+                       "\xcd\x76\x95\xb8\x7a\x82\x7f\x21"
+                       "\x45\xff\x3f\xce\x55\xf6\x95\x10"
+                       "\x08\x77\x10\x43\xc6\xf3\x09\xe5"
+                       "\x68\xe7\x3c\xad\x00\x52\x45\x0d"
+                       "\xfe\x2d\xc6\xc2\x94\x8c\x12\x1d"
+                       "\xe6\x25\xae\x98\x12\x8e\x19\x9c"
+                       "\x81\x68\xb1\x11\xf6\x69\xda\xe3"
+                       "\x62\x08\x18\x7a\x25\x49\x28\xac"
+                       "\xba\x71\x12\x0b\xe4\xa2\xe5\xc7"
+                       "\x5d\x8e\xec\x49\x40\x21\xbf\x5a"
+                       "\x98\xf3\x02\x68\x55\x03\x7f\x8a"
+                       "\xe5\x94\x0c\x32\x5c\x07\x82\x63"
+                       "\xaf\x6f\x91\x40\x84\x8e\x52\x25"
+                       "\xd0\xb0\x29\x53\x05\xe2\x50\x7a"
+                       "\x34\xeb\xc9\x46\x20\xa8\x3d\xde"
+                       "\x7f\x16\x5f\x36\xc5\x2e\xdc\xd1"
+                       "\x15\x47\xc7\x50\x40\x6d\x91\xc5"
+                       "\xe7\x93\x95\x1a\xd3\x57\xbc\x52"
+                       "\x33\xee\x14\x19\x22\x52\x89\xa7"
+                       "\x4a\x25\x56\x77\x4b\xca\xcf\x0a"
+                       "\xe1\xf5\x35\x85\x30\x7e\x59\x4a"
+                       "\xbd\x14\x5b\xdf\xe3\x46\xcb\xac"
+                       "\x1f\x6c\x96\x0e\xf4\x81\xd1\x99"
+                       "\xca\x88\x63\x3d\x02\x58\x6b\xa9"
+                       "\xe5\x9f\xb3\x00\xb2\x54\xc6\x74"
+                       "\x1c\xbf\x46\xab\x97\xcc\xf8\x54"
+                       "\x04\x07\x08\x52\xe6\xc0\xda\x93"
+                       "\x74\x7d\x93\x99\x5d\x78\x68\xa6"
+                       "\x2e\x6b\xd3\x6a\x69\xcc\x12\x6b"
+                       "\xd4\xc7\xa5\xc6\xe7\xf6\x03\x04"
+                       "\x5d\xcd\x61\x5e\x17\x40\xdc\xd1"
+                       "\x5c\xf5\x08\xdf\x5c\x90\x85\xa4"
+                       "\xaf\xf6\x78\xbb\x0d\xf1\xf4\xa4"
+                       "\x54\x26\x72\x9e\x61\xfa\x86\xcf"
+                       "\xe8\x9e\xa1\xe0\xc7\x48\x23\xae"
+                       "\x5a\x90\xae\x75\x0a\x74\x18\x89"
+                       "\x05\xb1\x92\xb2\x7f\xd0\x1b\xa6"
+                       "\x62\x07\x25\x01\xc7\xc2\x4f\xf9"
+                       "\xe8\xfe\x63\x95\x80\x07\xb4\x26"
+                       "\xcc\xd1\x26\xb6\xc4\x3f\x9e\xcb"
+                       "\x8e\x3b\x2e\x44\x16\xd3\x10\x9a"
+                       "\x95\x08\xeb\xc8\xcb\xeb\xbf\x6f"
+                       "\x0b\xcd\x1f\xc8\xca\x86\xaa\xec"
+                       "\x33\xe6\x69\xf4\x45\x25\x86\x3a"
+                       "\x22\x94\x4f\x00\x23\x6a\x44\xc2"
+                       "\x49\x97\x33\xab\x36\x14\x0a\x70"
+                       "\x24\xc3\xbe\x04\x3b\x79\xa0\xf9"
+                       "\xb8\xe7\x76\x29\x22\x83\xd7\xf2"
+                       "\x94\xf4\x41\x49\xba\x5f\x7b\x07"
+                       "\xb5\xfb\xdb\x03\x1a\x9f\xb6\x4c"
+                       "\xc2\x2e\x37\x40\x49\xc3\x38\x16"
+                       "\xe2\x4f\x77\x82\xb0\x68\x4c\x71"
+                       "\x1d\x57\x61\x9c\xd9\x4e\x54\x99"
+                       "\x47\x13\x28\x73\x3c\xbb\x00\x90"
+                       "\xf3\x4d\xc9\x0e\xfd\xe7\xb1\x71"
+                       "\xd3\x15\x79\xbf\xcc\x26\x2f\xbd"
+                       "\xad\x6c\x50\x69\x6c\x3e\x6d\x80"
+                       "\x9a\xea\x78\xaf\x19\xb2\x0d\x4d"
+                       "\xad\x04\x07\xae\x22\x90\x4a\x93"
+                       "\x32\x0e\x36\x9b\x1b\x46\xba\x3b"
+                       "\xb4\xac\xc6\xd1\xa2\x31\x53\x3b"
+                       "\x2a\x3d\x45\xfe\x03\x61\x10\x85"
+                       "\x17\x69\xa6\x78\xcc\x6c\x87\x49"
+                       "\x53\xf9\x80\x10\xde\x80\xa2\x41"
+                       "\x6a\xc3\x32\x02\xad\x6d\x3c\x56"
+                       "\x00\x71\x51\x06\xa7\xbd\xfb\xef"
+                       "\x3c\xb5\x9f\xfc\x48\x7d\x53\x7c"
+                       "\x66\xb0\x49\x23\xc4\x47\x10\x0e"
+                       "\xe5\x6c\x74\x13\xe6\xc5\x3f\xaa"
+                       "\xde\xff\x07\x44\xdd\x56\x1b\xad"
+                       "\x09\x77\xfb\x5b\x12\xb8\x0d\x38"
+                       "\x17\x37\x35\x7b\x9b\xbc\xfe\xd4"
+                       "\x7e\x8b\xda\x7e\x5b\x04\xa7\x22"
+                       "\xa7\x31\xa1\x20\x86\xc7\x1b\x99"
+                       "\xdb\xd1\x89\xf4\x94\xa3\x53\x69"
+                       "\x8d\xe7\xe8\x74\x11\x8d\x74\xd6"
+                       "\x07\x37\x91\x9f\xfd\x67\x50\x3a"
+                       "\xc9\xe1\xf4\x36\xd5\xa0\x47\xd1"
+                       "\xf9\xe5\x39\xa3\x31\xac\x07\x36"
+                       "\x23\xf8\x66\x18\x14\x28\x34\x0f"
+                       "\xb8\xd0\xe7\x29\xb3\x04\x4b\x55"
+                       "\x01\x41\xb2\x75\x8d\xcb\x96\x85"
+                       "\x3a\xfb\xab\x2b\x9e\xfa\x58\x20"
+                       "\x44\x1f\xc0\x14\x22\x75\x61\xe8"
+                       "\xaa\x19\xcf\xf1\x82\x56\xf4\xd7"
+                       "\x78\x7b\x3d\x5f\xb3\x9e\x0b\x8a"
+                       "\x57\x50\xdb\x17\x41\x65\x4d\xa3"
+                       "\x02\xc9\x9c\x9c\x53\xfb\x39\x39"
+                       "\x9b\x1d\x72\x24\xda\xb7\x39\xbe"
+                       "\x13\x3b\xfa\x29\xda\x9e\x54\x64"
+                       "\x6e\xba\xd8\xa1\xcb\xb3\x36\xfa"
+                       "\xcb\x47\x85\xe9\x61\x38\xbc\xbe"
+                       "\xc5\x00\x38\x2a\x54\xf7\xc4\xb9"
+                       "\xb3\xd3\x7b\xa0\xa0\xf8\x72\x7f"
+                       "\x8c\x8e\x82\x0e\xc6\x1c\x75\x9d"
+                       "\xca\x8e\x61\x87\xde\xad\x80\xd2"
+                       "\xf5\xf9\x80\xef\x15\x75\xaf\xf5"
+                       "\x80\xfb\xff\x6d\x1e\x25\xb7\x40"
+                       "\x61\x6a\x39\x5a\x6a\xb5\x31\xab"
+                       "\x97\x8a\x19\x89\x44\x40\xc0\xa6"
+                       "\xb4\x4e\x30\x32\x7b\x13\xe7\x67"
+                       "\xa9\x8b\x57\x04\xc2\x01\xa6\xf4"
+                       "\x28\x99\xad\x2c\x76\xa3\x78\xc2"
+                       "\x4a\xe6\xca\x5c\x50\x6a\xc1\xb0"
+                       "\x62\x4b\x10\x8e\x7c\x17\x43\xb3"
+                       "\x17\x66\x1c\x3e\x8d\x69\xf0\x5a"
+                       "\x71\xf5\x97\xdc\xd1\x45\xdd\x28"
+                       "\xf3\x5d\xdf\x53\x7b\x11\xe5\xbc"
+                       "\x4c\xdb\x1b\x51\x6b\xe9\xfb\x3d"
+                       "\xc1\xc3\x2c\xb9\x71\xf5\xb6\xb2"
+                       "\x13\x36\x79\x80\x53\xe8\xd3\xa6"
+                       "\x0a\xaf\xfd\x56\x97\xf7\x40\x8e"
+                       "\x45\xce\xf8\xb0\x9e\x5c\x33\x82"
+                       "\xb0\x44\x56\xfc\x05\x09\xe9\x2a"
+                       "\xac\x26\x80\x14\x1d\xc8\x3a\x35"
+                       "\x4c\x82\x97\xfd\x76\xb7\xa9\x0a"
+                       "\x35\x58\x79\x8e\x0f\x66\xea\xaf"
+                       "\x51\x6c\x09\xa9\x6e\x9b\xcb\x9a"
+                       "\x31\x47\xa0\x2f\x7c\x71\xb4\x4a"
+                       "\x11\xaa\x8c\x66\xc5\x64\xe6\x3a"
+                       "\x54\xda\x24\x6a\xc4\x41\x65\x46"
+                       "\x82\xa0\x0a\x0f\x5f\xfb\x25\xd0"
+                       "\x2c\x91\xa7\xee\xc4\x81\x07\x86"
+                       "\x75\x5e\x33\x69\x97\xe4\x2c\xa8"
+                       "\x9d\x9f\x0b\x6a\xbe\xad\x98\xda"
+                       "\x6d\x94\x41\xda\x2c\x1e\x89\xc4"
+                       "\xc2\xaf\x1e\x00\x05\x0b\x83\x60"
+                       "\xbd\x43\xea\x15\x23\x7f\xb9\xac"
+                       "\xee\x4f\x2c\xaf\x2a\xf3\xdf\xd0"
+                       "\xf3\x19\x31\xbb\x4a\x74\x84\x17"
+                       "\x52\x32\x2c\x7d\x61\xe4\xcb\xeb"
+                       "\x80\x38\x15\x52\xcb\x6f\xea\xe5"
+                       "\x73\x9c\xd9\x24\x69\xc6\x95\x32"
+                       "\x21\xc8\x11\xe4\xdc\x36\xd7\x93"
+                       "\x38\x66\xfb\xb2\x7f\x3a\xb9\xaf"
+                       "\x31\xdd\x93\x75\x78\x8a\x2c\x94"
+                       "\x87\x1a\x58\xec\x9e\x7d\x4d\xba"
+                       "\xe1\xe5\x4d\xfc\xbc\xa4\x2a\x14"
+                       "\xef\xcc\xa7\xec\xab\x43\x09\x18"
+                       "\xd3\xab\x68\xd1\x07\x99\x44\x47"
+                       "\xd6\x83\x85\x3b\x30\xea\xa9\x6b"
+                       "\x63\xea\xc4\x07\xfb\x43\x2f\xa4"
+                       "\xaa\xb0\xab\x03\x89\xce\x3f\x8c"
+                       "\x02\x7c\x86\x54\xbc\x88\xaf\x75"
+                       "\xd2\xdc\x63\x17\xd3\x26\xf6\x96"
+                       "\xa9\x3c\xf1\x61\x8c\x11\x18\xcc"
+                       "\xd6\xea\x5b\xe2\xcd\xf0\xf1\xb2"
+                       "\xe5\x35\x90\x1f\x85\x4c\x76\x5b"
+                       "\x66\xce\x44\xa4\x32\x9f\xe6\x7b"
+                       "\x71\x6e\x9f\x58\x15\x67\x72\x87"
+                       "\x64\x8e\x3a\x44\x45\xd4\x76\xfa"
+                       "\xc2\xf6\xef\x85\x05\x18\x7a\x9b"
+                       "\xba\x41\x54\xac\xf0\xfc\x59\x12"
+                       "\x3f\xdf\xa0\xe5\x8a\x65\xfd\x3a"
+                       "\x62\x8d\x83\x2c\x03\xbe\x05\x76"
+                       "\x2e\x53\x49\x97\x94\x33\xae\x40"
+                       "\x81\x15\xdb\x6e\xad\xaa\xf5\x4b"
+                       "\xe3\x98\x70\xdf\xe0\x7c\xcd\xdb"
+                       "\x02\xd4\x7d\x2f\xc1\xe6\xb4\xf3"
+                       "\xd7\x0d\x7a\xd9\x23\x9e\x87\x2d"
+                       "\xce\x87\xad\xcc\x72\x05\x00\x29"
+                       "\xdc\x73\x7f\x64\xc1\x15\x0e\xc2"
+                       "\xdf\xa7\x5f\xeb\x41\xa1\xcd\xef"
+                       "\x5c\x50\x79\x2a\x56\x56\x71\x8c"
+                       "\xac\xc0\x79\x50\x69\xca\x59\x32"
+                       "\x65\xf2\x54\xe4\x52\x38\x76\xd1"
+                       "\x5e\xde\x26\x9e\xfb\x75\x2e\x11"
+                       "\xb5\x10\xf4\x17\x73\xf5\x89\xc7"
+                       "\x4f\x43\x5c\x8e\x7c\xb9\x05\x52"
+                       "\x24\x40\x99\xfe\x9b\x85\x0b\x6c"
+                       "\x22\x3e\x8b\xae\x86\xa1\xd2\x79"
+                       "\x05\x68\x6b\xab\xe3\x41\x49\xed"
+                       "\x15\xa1\x8d\x40\x2d\x61\xdf\x1a"
+                       "\x59\xc9\x26\x8b\xef\x30\x4c\x88"
+                       "\x4b\x10\xf8\x8d\xa6\x92\x9f\x4b"
+                       "\xf3\xc4\x53\x0b\x89\x5d\x28\x92"
+                       "\xcf\x78\xb2\xc0\x5d\xed\x7e\xfc"
+                       "\xc0\x12\x23\x5f\x5a\x78\x86\x43"
+                       "\x6e\x27\xf7\x5a\xa7\x6a\xed\x19"
+                       "\x04\xf0\xb3\x12\xd1\xbd\x0e\x89"
+                       "\x6e\xbc\x96\xa8\xd8\x49\x39\x9f"
+                       "\x7e\x67\xf0\x2e\x3e\x01\xa9\xba"
+                       "\xec\x8b\x62\x8e\xcb\x4a\x70\x43"
+                       "\xc7\xc2\xc4\xca\x82\x03\x73\xe9"
+                       "\x11\xdf\xcf\x54\xea\xc9\xb0\x95"
+                       "\x51\xc0\x13\x3d\x92\x05\xfa\xf4"
+                       "\xa9\x34\xc8\xce\x6c\x3d\x54\xcc"
+                       "\xc4\xaf\xf1\xdc\x11\x44\x26\xa2"
+                       "\xaf\xf1\x85\x75\x7d\x03\x61\x68"
+                       "\x4e\x78\xc6\x92\x7d\x86\x7d\x77"
+                       "\xdc\x71\x72\xdb\xc6\xae\xa1\xcb"
+                       "\x70\x9a\x0b\x19\xbe\x4a\x6c\x2a"
+                       "\xe2\xba\x6c\x64\x9a\x13\x28\xdf"
+                       "\x85\x75\xe6\x43\xf6\x87\x08\x68"
+                       "\x6e\xba\x6e\x79\x9f\x04\xbc\x23"
+                       "\x50\xf6\x33\x5c\x1f\x24\x25\xbe"
+                       "\x33\x47\x80\x45\x56\xa3\xa7\xd7"
+                       "\x7a\xb1\x34\x0b\x90\x3c\x9c\xad"
+                       "\x44\x5f\x9e\x0e\x9d\xd4\xbd\x93"
+                       "\x5e\xfa\x3c\xe0\xb0\xd9\xed\xf3"
+                       "\xd6\x2e\xff\x24\xd8\x71\x6c\xed"
+                       "\xaf\x55\xeb\x22\xac\x93\x68\x32"
+                       "\x05\x5b\x47\xdd\xc6\x4a\xcb\xc7"
+                       "\x10\xe1\x3c\x92\x1a\xf3\x23\x78"
+                       "\x2b\xa1\xd2\x80\xf4\x12\xb1\x20"
+                       "\x8f\xff\x26\x35\xdd\xfb\xc7\x4e"
+                       "\x78\xf1\x2d\x50\x12\x77\xa8\x60"
+                       "\x7c\x0f\xf5\x16\x2f\x63\x70\x2a"
+                       "\xc0\x96\x80\x4e\x0a\xb4\x93\x35"
+                       "\x5d\x1d\x3f\x56\xf7\x2f\xbb\x90"
+                       "\x11\x16\x8f\xa2\xec\x47\xbe\xac"
+                       "\x56\x01\x26\x56\xb1\x8c\xb2\x10"
+                       "\xf9\x1a\xca\xf5\xd1\xb7\x39\x20"
+                       "\x63\xf1\x69\x20\x4f\x13\x12\x1f"
+                       "\x5b\x65\xfc\x98\xf7\xc4\x7a\xbe"
+                       "\xf7\x26\x4d\x2b\x84\x7b\x42\xad"
+                       "\xd8\x7a\x0a\xb4\xd8\x74\xbf\xc1"
+                       "\xf0\x6e\xb4\x29\xa3\xbb\xca\x46"
+                       "\x67\x70\x6a\x2d\xce\x0e\xa2\x8a"
+                       "\xa9\x87\xbf\x05\xc4\xc1\x04\xa3"
+                       "\xab\xd4\x45\x43\x8c\xb6\x02\xb0"
+                       "\x41\xc8\xfc\x44\x3d\x59\xaa\x2e"
+                       "\x44\x21\x2a\x8d\x88\x9d\x57\xf4"
+                       "\xa0\x02\x77\xb8\xa6\xa0\xe6\x75"
+                       "\x5c\x82\x65\x3e\x03\x5c\x29\x8f"
+                       "\x38\x55\xab\x33\x26\xef\x9f\x43"
+                       "\x52\xfd\x68\xaf\x36\xb4\xbb\x9a"
+                       "\x58\x09\x09\x1b\xc3\x65\x46\x46"
+                       "\x1d\xa7\x94\x18\x23\x50\x2c\xca"
+                       "\x2c\x55\x19\x97\x01\x9d\x93\x3b"
+                       "\x63\x86\xf2\x03\x67\x45\xd2\x72"
+                       "\x28\x52\x6c\xf4\xe3\x1c\xb5\x11"
+                       "\x13\xf1\xeb\x21\xc7\xd9\x56\x82"
+                       "\x2b\x82\x39\xbd\x69\x54\xed\x62"
+                       "\xc3\xe2\xde\x73\xd4\x6a\x12\xae"
+                       "\x13\x21\x7f\x4b\x5b\xfc\xbf\xe8"
+                       "\x2b\xbe\x56\xba\x68\x8b\x9a\xb1"
+                       "\x6e\xfa\xbf\x7e\x5a\x4b\xf1\xac"
+                       "\x98\x65\x85\xd1\x93\x53\xd3\x7b"
+                       "\x09\xdd\x4b\x10\x6d\x84\xb0\x13"
+                       "\x65\xbd\xcf\x52\x09\xc4\x85\xe2"
+                       "\x84\x74\x15\x65\xb7\xf7\x51\xaf"
+                       "\x55\xad\xa4\xd1\x22\x54\x70\x94"
+                       "\xa0\x1c\x90\x41\xfd\x99\xd7\x5a"
+                       "\x31\xef\xaa\x25\xd0\x7f\x4f\xea"
+                       "\x1d\x55\x42\xe5\x49\xb0\xd0\x46"
+                       "\x62\x36\x43\xb2\x82\x15\x75\x50"
+                       "\xa4\x72\xeb\x54\x27\x1f\x8a\xe4"
+                       "\x7d\xe9\x66\xc5\xf1\x53\xa4\xd1"
+                       "\x0c\xeb\xb8\xf8\xbc\xd4\xe2\xe7"
+                       "\xe1\xf8\x4b\xcb\xa9\xa1\xaf\x15"
+                       "\x83\xcb\x72\xd0\x33\x79\x00\x2d"
+                       "\x9f\xd7\xf1\x2e\x1e\x10\xe4\x45"
+                       "\xc0\x75\x3a\x39\xea\x68\xf7\x5d"
+                       "\x1b\x73\x8f\xe9\x8e\x0f\x72\x47"
+                       "\xae\x35\x0a\x31\x7a\x14\x4d\x4a"
+                       "\x6f\x47\xf7\x7e\x91\x6e\x74\x8b"
+                       "\x26\x47\xf9\xc3\xf9\xde\x70\xf5"
+                       "\x61\xab\xa9\x27\x9f\x82\xe4\x9c"
+                       "\x89\x91\x3f\x2e\x6a\xfd\xb5\x49"
+                       "\xe9\xfd\x59\x14\x36\x49\x40\x6d"
+                       "\x32\xd8\x85\x42\xf3\xa5\xdf\x0c"
+                       "\xa8\x27\xd7\x54\xe2\x63\x2f\xf2"
+                       "\x7e\x8b\x8b\xe7\xf1\x9a\x95\x35"
+                       "\x43\xdc\x3a\xe4\xb6\xf4\xd0\xdf"
+                       "\x9c\xcb\x94\xf3\x21\xa0\x77\x50"
+                       "\xe2\xc6\xc4\xc6\x5f\x09\x64\x5b"
+                       "\x92\x90\xd8\xe1\xd1\xed\x4b\x42"
+                       "\xd7\x37\xaf\x65\x3d\x11\x39\xb6"
+                       "\x24\x8a\x60\xae\xd6\x1e\xbf\x0e"
+                       "\x0d\xd7\xdc\x96\x0e\x65\x75\x4e"
+                       "\x29\x06\x9d\xa4\x51\x3a\x10\x63"
+                       "\x8f\x17\x07\xd5\x8e\x3c\xf4\x28"
+                       "\x00\x5a\x5b\x05\x19\xd8\xc0\x6c"
+                       "\xe5\x15\xe4\x9c\x9d\x71\x9d\x5e"
+                       "\x94\x29\x1a\xa7\x80\xfa\x0e\x33"
+                       "\x03\xdd\xb7\x3e\x9a\xa9\x26\x18"
+                       "\x37\xa9\x64\x08\x4d\x94\x5a\x88"
+                       "\xca\x35\xce\x81\x02\xe3\x1f\x1b"
+                       "\x89\x1a\x77\x85\xe3\x41\x6d\x32"
+                       "\x42\x19\x23\x7d\xc8\x73\xee\x25"
+                       "\x85\x0d\xf8\x31\x25\x79\x1b\x6f"
+                       "\x79\x25\xd2\xd8\xd4\x23\xfd\xf7"
+                       "\x82\x36\x6a\x0c\x46\x22\x15\xe9"
+                       "\xff\x72\x41\x91\x91\x7d\x3a\xb7"
+                       "\xdd\x65\x99\x70\xf6\x8d\x84\xf8"
+                       "\x67\x15\x20\x11\xd6\xb2\x55\x7b"
+                       "\xdb\x87\xee\xef\x55\x89\x2a\x59"
+                       "\x2b\x07\x8f\x43\x8a\x59\x3c\x01"
+                       "\x8b\x65\x54\xa1\x66\xd5\x38\xbd"
+                       "\xc6\x30\xa9\xcc\x49\xb6\xa8\x1b"
+                       "\xb8\xc0\x0e\xe3\x45\x28\xe2\xff"
+                       "\x41\x9f\x7e\x7c\xd1\xae\x9e\x25"
+                       "\x3f\x4c\x7c\x7c\xf4\xa8\x26\x4d"
+                       "\x5c\xfd\x4b\x27\x18\xf9\x61\x76"
+                       "\x48\xba\x0c\x6b\xa9\x4d\xfc\xf5"
+                       "\x3b\x35\x7e\x2f\x4a\xa9\xc2\x9a"
+                       "\xae\xab\x86\x09\x89\xc9\xc2\x40"
+                       "\x39\x2c\x81\xb3\xb8\x17\x67\xc2"
+                       "\x0d\x32\x4a\x3a\x67\x81\xd7\x1a"
+                       "\x34\x52\xc5\xdb\x0a\xf5\x63\x39"
+                       "\xea\x1f\xe1\x7c\xa1\x9e\xc1\x35"
+                       "\xe3\xb1\x18\x45\x67\xf9\x22\x38"
+                       "\x95\xd9\x34\x34\x86\xc6\x41\x94"
+                       "\x15\xf9\x5b\x41\xa6\x87\x8b\xf8"
+                       "\xd5\xe1\x1b\xe2\x5b\xf3\x86\x10"
+                       "\xff\xe6\xae\x69\x76\xbc\x0d\xb4"
+                       "\x09\x90\x0c\xa2\x65\x0c\xad\x74"
+                       "\xf5\xd7\xff\xda\xc1\xce\x85\xbe"
+                       "\x00\xa7\xff\x4d\x2f\x65\xd3\x8c"
+                       "\x86\x2d\x05\xe8\xed\x3e\x6b\x8b"
+                       "\x0f\x3d\x83\x8c\xf1\x1d\x5b\x96"
+                       "\x2e\xb1\x9c\xc2\x98\xe1\x70\xb9"
+                       "\xba\x5c\x8a\x43\xd6\x34\xa7\x2d"
+                       "\xc9\x92\xae\xf2\xa5\x7b\x05\x49"
+                       "\xa7\x33\x34\x86\xca\xe4\x96\x23"
+                       "\x76\x5b\xf2\xc6\xf1\x51\x28\x42"
+                       "\x7b\xcc\x76\x8f\xfa\xa2\xad\x31"
+                       "\xd4\xd6\x7a\x6d\x25\x25\x54\xe4"
+                       "\x3f\x50\x59\xe1\x5c\x05\xb7\x27"
+                       "\x48\xbf\x07\xec\x1b\x13\xbe\x2b"
+                       "\xa1\x57\x2b\xd5\xab\xd7\xd0\x4c"
+                       "\x1e\xcb\x71\x9b\xc5\x90\x85\xd3"
+                       "\xde\x59\xec\x71\xeb\x89\xbb\xd0"
+                       "\x09\x50\xe1\x16\x3f\xfd\x1c\x34"
+                       "\xc3\x1c\xa1\x10\x77\x53\x98\xef"
+                       "\xf2\xfd\xa5\x01\x59\xc2\x9b\x26"
+                       "\xc7\x42\xd9\x49\xda\x58\x2b\x6e"
+                       "\x9f\x53\x19\x76\x7e\xd9\xc9\x0e"
+                       "\x68\xc8\x7f\x51\x22\x42\xef\x49"
+                       "\xa4\x55\xb6\x36\xac\x09\xc7\x31"
+                       "\x88\x15\x4b\x2e\x8f\x3a\x08\xf7"
+                       "\xd8\xf7\xa8\xc5\xa9\x33\xa6\x45"
+                       "\xe4\xc4\x94\x76\xf3\x0d\x8f\x7e"
+                       "\xc8\xf6\xbc\x23\x0a\xb6\x4c\xd3"
+                       "\x6a\xcd\x36\xc2\x90\x5c\x5c\x3c"
+                       "\x65\x7b\xc2\xd6\xcc\xe6\x0d\x87"
+                       "\x73\x2e\x71\x79\x16\x06\x63\x28"
+                       "\x09\x15\xd8\x89\x38\x38\x3d\xb5"
+                       "\x42\x1c\x08\x24\xf7\x2a\xd2\x9d"
+                       "\xc8\xca\xef\xf9\x27\xd8\x07\x86"
+                       "\xf7\x43\x0b\x55\x15\x3f\x9f\x83"
+                       "\xef\xdc\x49\x9d\x2a\xc1\x54\x62"
+                       "\xbd\x9b\x66\x55\x9f\xb7\x12\xf3"
+                       "\x1b\x4d\x9d\x2a\x5c\xed\x87\x75"
+                       "\x87\x26\xec\x61\x2c\xb4\x0f\x89"
+                       "\xb0\xfb\x2e\x68\x5d\x15\xc7\x8d"
+                       "\x2e\xc0\xd9\xec\xaf\x4f\xd2\x25"
+                       "\x29\xe8\xd2\x26\x2b\x67\xe9\xfc"
+                       "\x2b\xa8\x67\x96\x12\x1f\x5b\x96"
+                       "\xc6\x14\x53\xaf\x44\xea\xd6\xe2"
+                       "\x94\x98\xe4\x12\x93\x4c\x92\xe0"
+                       "\x18\xa5\x8d\x2d\xe4\x71\x3c\x47"
+                       "\x4c\xf7\xe6\x47\x9e\xc0\x68\xdf"
+                       "\xd4\xf5\x5a\x74\xb1\x2b\x29\x03"
+                       "\x19\x07\xaf\x90\x62\x5c\x68\x98"
+                       "\x48\x16\x11\x02\x9d\xee\xb4\x9b"
+                       "\xe5\x42\x7f\x08\xfd\x16\x32\x0b"
+                       "\xd0\xb3\xfa\x2b\xb7\x99\xf9\x29"
+                       "\xcd\x20\x45\x9f\xb3\x1a\x5d\xa2"
+                       "\xaf\x4d\xe0\xbd\x42\x0d\xbc\x74"
+                       "\x99\x9c\x8e\x53\x1a\xb4\x3e\xbd"
+                       "\xa2\x9a\x2d\xf7\xf8\x39\x0f\x67"
+                       "\x63\xfc\x6b\xc0\xaf\xb3\x4b\x4f"
+                       "\x55\xc4\xcf\xa7\xc8\x04\x11\x3e"
+                       "\x14\x32\xbb\x1b\x38\x77\xd6\x7f"
+                       "\x54\x4c\xdf\x75\xf3\x07\x2d\x33"
+                       "\x9b\xa8\x20\xe1\x7b\x12\xb5\xf3"
+                       "\xef\x2f\xce\x72\xe5\x24\x60\xc1"
+                       "\x30\xe2\xab\xa1\x8e\x11\x09\xa8"
+                       "\x21\x33\x44\xfe\x7f\x35\x32\x93"
+                       "\x39\xa7\xad\x8b\x79\x06\xb2\xcb"
+                       "\x4e\xa9\x5f\xc7\xba\x74\x29\xec"
+                       "\x93\xa0\x4e\x54\x93\xc0\xbc\x55"
+                       "\x64\xf0\x48\xe5\x57\x99\xee\x75"
+                       "\xd6\x79\x0f\x66\xb7\xc6\x57\x76"
+                       "\xf7\xb7\xf3\x9c\xc5\x60\xe8\x7f"
+                       "\x83\x76\xd6\x0e\xaa\xe6\x90\x39"
+                       "\x1d\xa6\x32\x6a\x34\xe3\x55\xf8"
+                       "\x58\xa0\x58\x7d\x33\xe0\x22\x39"
+                       "\x44\x64\x87\x86\x5a\x2f\xa7\x7e"
+                       "\x0f\x38\xea\xb0\x30\xcc\x61\xa5"
+                       "\x6a\x32\xae\x1e\xf7\xe9\xd0\xa9"
+                       "\x0c\x32\x4b\xb5\x49\x28\xab\x85"
+                       "\x2f\x8e\x01\x36\x38\x52\xd0\xba"
+                       "\xd6\x02\x78\xf8\x0e\x3e\x9c\x8b"
+                       "\x6b\x45\x99\x3f\x5c\xfe\x58\xf1"
+                       "\x5c\x94\x04\xe1\xf5\x18\x6d\x51"
+                       "\xb2\x5d\x18\x20\xb6\xc2\x9a\x42"
+                       "\x1d\xb3\xab\x3c\xb6\x3a\x13\x03"
+                       "\xb2\x46\x82\x4f\xfc\x64\xbc\x4f"
+                       "\xca\xfa\x9c\xc0\xd5\xa7\xbd\x11"
+                       "\xb7\xe4\x5a\xf6\x6f\x4d\x4d\x54"
+                       "\xea\xa4\x98\x66\xd4\x22\x3b\xd3"
+                       "\x8f\x34\x47\xd9\x7c\xf4\x72\x3b"
+                       "\x4d\x02\x77\xf6\xd6\xdd\x08\x0a"
+                       "\x81\xe1\x86\x89\x3e\x56\x10\x3c"
+                       "\xba\xd7\x81\x8c\x08\xbc\x8b\xe2"
+                       "\x53\xec\xa7\x89\xee\xc8\x56\xb5"
+                       "\x36\x2c\xb2\x03\xba\x99\xdd\x7c"
+                       "\x48\xa0\xb0\xbc\x91\x33\xe9\xa8"
+                       "\xcb\xcd\xcf\x59\x5f\x1f\x15\xe2"
+                       "\x56\xf5\x4e\x01\x35\x27\x45\x77"
+                       "\x47\xc8\xbc\xcb\x7e\x39\xc1\x97"
+                       "\x28\xd3\x84\xfc\x2c\x3e\xc8\xad"
+                       "\x9c\xf8\x8a\x61\x9c\x28\xaa\xc5"
+                       "\x99\x20\x43\x85\x9d\xa5\xe2\x8b"
+                       "\xb8\xae\xeb\xd0\x32\x0d\x52\x78"
+                       "\x09\x56\x3f\xc7\xd8\x7e\x26\xfc"
+                       "\x37\xfb\x6f\x04\xfc\xfa\x92\x10"
+                       "\xac\xf8\x3e\x21\xdc\x8c\x21\x16"
+                       "\x7d\x67\x6e\xf6\xcd\xda\xb6\x98"
+                       "\x23\xab\x23\x3c\xb2\x10\xa0\x53"
+                       "\x5a\x56\x9f\xc5\xd0\xff\xbb\xe4"
+                       "\x98\x3c\x69\x1e\xdb\x38\x8f\x7e"
+                       "\x0f\xd2\x98\x88\x81\x8b\x45\x67"
+                       "\xea\x33\xf1\xeb\xe9\x97\x55\x2e"
+                       "\xd9\xaa\xeb\x5a\xec\xda\xe1\x68"
+                       "\xa8\x9d\x3c\x84\x7c\x05\x3d\x62"
+                       "\x87\x8f\x03\x21\x28\x95\x0c\x89"
+                       "\x25\x22\x4a\xb0\x93\xa9\x50\xa2"
+                       "\x2f\x57\x6e\x18\x42\x19\x54\x0c"
+                       "\x55\x67\xc6\x11\x49\xf4\x5c\xd2"
+                       "\xe9\x3d\xdd\x8b\x48\x71\x21\x00"
+                       "\xc3\x9a\x6c\x85\x74\x28\x83\x4a"
+                       "\x1b\x31\x05\xe1\x06\x92\xe7\xda"
+                       "\x85\x73\x78\x45\x20\x7f\xae\x13"
+                       "\x7c\x33\x06\x22\xf4\x83\xf9\x35"
+                       "\x3f\x6c\x71\xa8\x4e\x48\xbe\x9b"
+                       "\xce\x8a\xba\xda\xbe\x28\x08\xf7"
+                       "\xe2\x14\x8c\x71\xea\x72\xf9\x33"
+                       "\xf2\x88\x3f\xd7\xbb\x69\x6c\x29"
+                       "\x19\xdc\x84\xce\x1f\x12\x4f\xc8"
+                       "\xaf\xa5\x04\xba\x5a\xab\xb0\xd9"
+                       "\x14\x1f\x6c\x68\x98\x39\x89\x7a"
+                       "\xd9\xd8\x2f\xdf\xa8\x47\x4a\x25"
+                       "\xe2\xfb\x33\xf4\x59\x78\xe1\x68"
+                       "\x85\xcf\xfe\x59\x20\xd4\x05\x1d"
+                       "\x80\x99\xae\xbc\xca\xae\x0f\x2f"
+                       "\x65\x43\x34\x8e\x7e\xac\xd3\x93"
+                       "\x2f\xac\x6d\x14\x3d\x02\x07\x70"
+                       "\x9d\xa4\xf3\x1b\x5c\x36\xfc\x01"
+                       "\x73\x34\x85\x0c\x6c\xd6\xf1\xbd"
+                       "\x3f\xdf\xee\xf5\xd9\xba\x56\xef"
+                       "\xf4\x9b\x6b\xee\x9f\x5a\x78\x6d"
+                       "\x32\x19\xf4\xf7\xf8\x4c\x69\x0b"
+                       "\x4b\xbc\xbb\xb7\xf2\x85\xaf\x70"
+                       "\x75\x24\x6c\x54\xa7\x0e\x4d\x1d"
+                       "\x01\xbf\x08\xac\xcf\x7f\x2c\xe3"
+                       "\x14\x89\x5e\x70\x5a\x99\x92\xcd"
+                       "\x01\x84\xc8\xd2\xab\xe5\x4f\x58"
+                       "\xe7\x0f\x2f\x0e\xff\x68\xea\xfd"
+                       "\x15\xb3\x17\xe6\xb0\xe7\x85\xd8"
+                       "\x23\x2e\x05\xc7\xc9\xc4\x46\x1f"
+                       "\xe1\x9e\x49\x20\x23\x24\x4d\x7e"
+                       "\x29\x65\xff\xf4\xb6\xfd\x1a\x85"
+                       "\xc4\x16\xec\xfc\xea\x7b\xd6\x2c"
+                       "\x43\xf8\xb7\xbf\x79\xc0\x85\xcd"
+                       "\xef\xe1\x98\xd3\xa5\xf7\x90\x8c"
+                       "\xe9\x7f\x80\x6b\xd2\xac\x4c\x30"
+                       "\xa7\xc6\x61\x6c\xd2\xf9\x2c\xff"
+                       "\x30\xbc\x22\x81\x7d\x93\x12\xe4"
+                       "\x0a\xcd\xaf\xdd\xe8\xab\x0a\x1e"
+                       "\x13\xa4\x27\xc3\x5f\xf7\x4b\xbb"
+                       "\x37\x09\x4b\x91\x6f\x92\x4f\xaf"
+                       "\x52\xee\xdf\xef\x09\x6f\xf7\x5c"
+                       "\x6e\x12\x17\x72\x63\x57\xc7\xba"
+                       "\x3b\x6b\x38\x32\x73\x1b\x9c\x80"
+                       "\xc1\x7a\xc6\xcf\xcd\x35\xc0\x6b"
+                       "\x31\x1a\x6b\xe9\xd8\x2c\x29\x3f"
+                       "\x96\xfb\xb6\xcd\x13\x91\x3b\xc2"
+                       "\xd2\xa3\x31\x8d\xa4\xcd\x57\xcd"
+                       "\x13\x3d\x64\xfd\x06\xce\xe6\xdc"
+                       "\x0c\x24\x43\x31\x40\x57\xf1\x72"
+                       "\x17\xe3\x3a\x63\x6d\x35\xcf\x5d"
+                       "\x97\x40\x59\xdd\xf7\x3c\x02\xf7"
+                       "\x1c\x7e\x05\xbb\xa9\x0d\x01\xb1"
+                       "\x8e\xc0\x30\xa9\x53\x24\xc9\x89"
+                       "\x84\x6d\xaa\xd0\xcd\x91\xc2\x4d"
+                       "\x91\xb0\x89\xe2\xbf\x83\x44\xaa"
+                       "\x28\x72\x23\xa0\xc2\xad\xad\x1c"
+                       "\xfc\x3f\x09\x7a\x0b\xdc\xc5\x1b"
+                       "\x87\x13\xc6\x5b\x59\x8d\xf2\xc8"
+                       "\xaf\xdf\x11\x95",
+               .rlen   = 4100,
+               .np     = 2,
+               .tap    = { 4064, 36 },
+       },
+};
+
+/*
+ * CTS (Cipher Text Stealing) mode tests
+ */
+#define CTS_MODE_ENC_TEST_VECTORS 6
+#define CTS_MODE_DEC_TEST_VECTORS 6
+static struct cipher_testvec cts_mode_enc_tv_template[] = {
+       { /* from rfc3962 */
+               .klen   = 16,
+               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
+               .ilen   = 17,
+               .input  = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+                         "\x20",
+               .rlen   = 17,
+               .result = "\xc6\x35\x35\x68\xf2\xbf\x8c\xb4"
+                         "\xd8\xa5\x80\x36\x2d\xa7\xff\x7f"
+                         "\x97",
+       }, {
+               .klen   = 16,
+               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
+               .ilen   = 31,
+               .input  = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+                         "\x20\x47\x61\x75\x27\x73\x20",
+               .rlen   = 31,
+               .result = "\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1"
+                         "\xd4\x45\xd4\xc8\xef\xf7\xed\x22"
+                         "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5",
+       }, {
+               .klen   = 16,
+               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
+               .ilen   = 32,
+               .input  = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+                         "\x20\x47\x61\x75\x27\x73\x20\x43",
+               .rlen   = 32,
+               .result = "\x39\x31\x25\x23\xa7\x86\x62\xd5"
+                         "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
+                         "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84",
+       }, {
+               .klen   = 16,
+               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
+               .ilen   = 47,
+               .input  = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+                         "\x20\x47\x61\x75\x27\x73\x20\x43"
+                         "\x68\x69\x63\x6b\x65\x6e\x2c\x20"
+                         "\x70\x6c\x65\x61\x73\x65\x2c",
+               .rlen   = 47,
+               .result = "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
+                         "\xb3\xff\xfd\x94\x0c\x16\xa1\x8c"
+                         "\x1b\x55\x49\xd2\xf8\x38\x02\x9e"
+                         "\x39\x31\x25\x23\xa7\x86\x62\xd5"
+                         "\xbe\x7f\xcb\xcc\x98\xeb\xf5",
+       }, {
+               .klen   = 16,
+               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
+               .ilen   = 48,
+               .input  = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+                         "\x20\x47\x61\x75\x27\x73\x20\x43"
+                         "\x68\x69\x63\x6b\x65\x6e\x2c\x20"
+                         "\x70\x6c\x65\x61\x73\x65\x2c\x20",
+               .rlen   = 48,
+               .result = "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
+                         "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0"
+                         "\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8"
+                         "\x39\x31\x25\x23\xa7\x86\x62\xd5"
+                         "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8",
+       }, {
+               .klen   = 16,
+               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
+               .ilen   = 64,
+               .input  = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+                         "\x20\x47\x61\x75\x27\x73\x20\x43"
+                         "\x68\x69\x63\x6b\x65\x6e\x2c\x20"
+                         "\x70\x6c\x65\x61\x73\x65\x2c\x20"
+                         "\x61\x6e\x64\x20\x77\x6f\x6e\x74"
+                         "\x6f\x6e\x20\x73\x6f\x75\x70\x2e",
+               .rlen   = 64,
+               .result = "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
+                         "\x39\x31\x25\x23\xa7\x86\x62\xd5"
+                         "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
+                         "\x48\x07\xef\xe8\x36\xee\x89\xa5"
+                         "\x26\x73\x0d\xbc\x2f\x7b\xc8\x40"
+                         "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0"
+                         "\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8",
+       }
+};
+
+static struct cipher_testvec cts_mode_dec_tv_template[] = {
+       { /* from rfc3962 */
+               .klen   = 16,
+               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
+               .rlen   = 17,
+               .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+                         "\x20",
+               .ilen   = 17,
+               .input  = "\xc6\x35\x35\x68\xf2\xbf\x8c\xb4"
+                         "\xd8\xa5\x80\x36\x2d\xa7\xff\x7f"
+                         "\x97",
+       }, {
+               .klen   = 16,
+               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
+               .rlen   = 31,
+               .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+                         "\x20\x47\x61\x75\x27\x73\x20",
+               .ilen   = 31,
+               .input  = "\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1"
+                         "\xd4\x45\xd4\xc8\xef\xf7\xed\x22"
+                         "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5",
+       }, {
+               .klen   = 16,
+               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
+               .rlen   = 32,
+               .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+                         "\x20\x47\x61\x75\x27\x73\x20\x43",
+               .ilen   = 32,
+               .input  = "\x39\x31\x25\x23\xa7\x86\x62\xd5"
+                         "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
+                         "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84",
+       }, {
+               .klen   = 16,
+               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
+               .rlen   = 47,
+               .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+                         "\x20\x47\x61\x75\x27\x73\x20\x43"
+                         "\x68\x69\x63\x6b\x65\x6e\x2c\x20"
+                         "\x70\x6c\x65\x61\x73\x65\x2c",
+               .ilen   = 47,
+               .input  = "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
+                         "\xb3\xff\xfd\x94\x0c\x16\xa1\x8c"
+                         "\x1b\x55\x49\xd2\xf8\x38\x02\x9e"
+                         "\x39\x31\x25\x23\xa7\x86\x62\xd5"
+                         "\xbe\x7f\xcb\xcc\x98\xeb\xf5",
+       }, {
+               .klen   = 16,
+               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
+               .rlen   = 48,
+               .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+                         "\x20\x47\x61\x75\x27\x73\x20\x43"
+                         "\x68\x69\x63\x6b\x65\x6e\x2c\x20"
+                         "\x70\x6c\x65\x61\x73\x65\x2c\x20",
+               .ilen   = 48,
+               .input  = "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
+                         "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0"
+                         "\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8"
+                         "\x39\x31\x25\x23\xa7\x86\x62\xd5"
+                         "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8",
+       }, {
+               .klen   = 16,
+               .key    = "\x63\x68\x69\x63\x6b\x65\x6e\x20"
+                         "\x74\x65\x72\x69\x79\x61\x6b\x69",
+               .rlen   = 64,
+               .result = "\x49\x20\x77\x6f\x75\x6c\x64\x20"
+                         "\x6c\x69\x6b\x65\x20\x74\x68\x65"
+                         "\x20\x47\x65\x6e\x65\x72\x61\x6c"
+                         "\x20\x47\x61\x75\x27\x73\x20\x43"
+                         "\x68\x69\x63\x6b\x65\x6e\x2c\x20"
+                         "\x70\x6c\x65\x61\x73\x65\x2c\x20"
+                         "\x61\x6e\x64\x20\x77\x6f\x6e\x74"
+                         "\x6f\x6e\x20\x73\x6f\x75\x70\x2e",
+               .ilen   = 64,
+               .input  = "\x97\x68\x72\x68\xd6\xec\xcc\xc0"
+                         "\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
+                         "\x39\x31\x25\x23\xa7\x86\x62\xd5"
+                         "\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
+                         "\x48\x07\xef\xe8\x36\xee\x89\xa5"
+                         "\x26\x73\x0d\xbc\x2f\x7b\xc8\x40"
+                         "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0"
+                         "\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8",
+       }
+};
+
+/*
+ * Compression stuff.
+ */
+#define COMP_BUF_SIZE           512
+
+struct comp_testvec {
+       int inlen, outlen;
+       char input[COMP_BUF_SIZE];
+       char output[COMP_BUF_SIZE];
+};
+
+/*
+ * Deflate test vectors (null-terminated strings).
+ * Params: winbits=11, Z_DEFAULT_COMPRESSION, MAX_MEM_LEVEL.
+ */
+#define DEFLATE_COMP_TEST_VECTORS 2
+#define DEFLATE_DECOMP_TEST_VECTORS 2
+
+static struct comp_testvec deflate_comp_tv_template[] = {
+       {
+               .inlen  = 70,
+               .outlen = 38,
+               .input  = "Join us now and share the software "
+                       "Join us now and share the software ",
+               .output = "\xf3\xca\xcf\xcc\x53\x28\x2d\x56"
+                         "\xc8\xcb\x2f\x57\x48\xcc\x4b\x51"
+                         "\x28\xce\x48\x2c\x4a\x55\x28\xc9"
+                         "\x48\x55\x28\xce\x4f\x2b\x29\x07"
+                         "\x71\xbc\x08\x2b\x01\x00",
+       }, {
+               .inlen  = 191,
+               .outlen = 122,
+               .input  = "This document describes a compression method based on the DEFLATE"
+                       "compression algorithm.  This document defines the application of "
+                       "the DEFLATE algorithm to the IP Payload Compression Protocol.",
+               .output = "\x5d\x8d\x31\x0e\xc2\x30\x10\x04"
+                         "\xbf\xb2\x2f\xc8\x1f\x10\x04\x09"
+                         "\x89\xc2\x85\x3f\x70\xb1\x2f\xf8"
+                         "\x24\xdb\x67\xd9\x47\xc1\xef\x49"
+                         "\x68\x12\x51\xae\x76\x67\xd6\x27"
+                         "\x19\x88\x1a\xde\x85\xab\x21\xf2"
+                         "\x08\x5d\x16\x1e\x20\x04\x2d\xad"
+                         "\xf3\x18\xa2\x15\x85\x2d\x69\xc4"
+                         "\x42\x83\x23\xb6\x6c\x89\x71\x9b"
+                         "\xef\xcf\x8b\x9f\xcf\x33\xca\x2f"
+                         "\xed\x62\xa9\x4c\x80\xff\x13\xaf"
+                         "\x52\x37\xed\x0e\x52\x6b\x59\x02"
+                         "\xd9\x4e\xe8\x7a\x76\x1d\x02\x98"
+                         "\xfe\x8a\x87\x83\xa3\x4f\x56\x8a"
+                         "\xb8\x9e\x8e\x5c\x57\xd3\xa0\x79"
+                         "\xfa\x02",
+       },
+};
+
+static struct comp_testvec deflate_decomp_tv_template[] = {
+       {
+               .inlen  = 122,
+               .outlen = 191,
+               .input  = "\x5d\x8d\x31\x0e\xc2\x30\x10\x04"
+                         "\xbf\xb2\x2f\xc8\x1f\x10\x04\x09"
+                         "\x89\xc2\x85\x3f\x70\xb1\x2f\xf8"
+                         "\x24\xdb\x67\xd9\x47\xc1\xef\x49"
+                         "\x68\x12\x51\xae\x76\x67\xd6\x27"
+                         "\x19\x88\x1a\xde\x85\xab\x21\xf2"
+                         "\x08\x5d\x16\x1e\x20\x04\x2d\xad"
+                         "\xf3\x18\xa2\x15\x85\x2d\x69\xc4"
+                         "\x42\x83\x23\xb6\x6c\x89\x71\x9b"
+                         "\xef\xcf\x8b\x9f\xcf\x33\xca\x2f"
+                         "\xed\x62\xa9\x4c\x80\xff\x13\xaf"
+                         "\x52\x37\xed\x0e\x52\x6b\x59\x02"
+                         "\xd9\x4e\xe8\x7a\x76\x1d\x02\x98"
+                         "\xfe\x8a\x87\x83\xa3\x4f\x56\x8a"
+                         "\xb8\x9e\x8e\x5c\x57\xd3\xa0\x79"
+                         "\xfa\x02",
+               .output = "This document describes a compression method based on the DEFLATE"
+                       "compression algorithm.  This document defines the application of "
+                       "the DEFLATE algorithm to the IP Payload Compression Protocol.",
+       }, {
+               .inlen  = 38,
+               .outlen = 70,
+               .input  = "\xf3\xca\xcf\xcc\x53\x28\x2d\x56"
+                         "\xc8\xcb\x2f\x57\x48\xcc\x4b\x51"
+                         "\x28\xce\x48\x2c\x4a\x55\x28\xc9"
+                         "\x48\x55\x28\xce\x4f\x2b\x29\x07"
+                         "\x71\xbc\x08\x2b\x01\x00",
+               .output = "Join us now and share the software "
+                       "Join us now and share the software ",
+       },
+};
+
+/*
+ * LZO test vectors (null-terminated strings).
+ */
+#define LZO_COMP_TEST_VECTORS 2
+#define LZO_DECOMP_TEST_VECTORS 2
+
+static struct comp_testvec lzo_comp_tv_template[] = {
+       {
+               .inlen  = 70,
+               .outlen = 46,
+               .input  = "Join us now and share the software "
+                       "Join us now and share the software ",
+               .output = "\x00\x0d\x4a\x6f\x69\x6e\x20\x75"
+                       "\x73\x20\x6e\x6f\x77\x20\x61\x6e"
+                       "\x64\x20\x73\x68\x61\x72\x65\x20"
+                       "\x74\x68\x65\x20\x73\x6f\x66\x74"
+                       "\x77\x70\x01\x01\x4a\x6f\x69\x6e"
+                       "\x3d\x88\x00\x11\x00\x00",
+       }, {
+               .inlen  = 159,
+               .outlen = 133,
+               .input  = "This document describes a compression method based on the LZO "
+                       "compression algorithm.  This document defines the application of "
+                       "the LZO algorithm used in UBIFS.",
+               .output = "\x00\x2b\x54\x68\x69\x73\x20\x64"
+                         "\x6f\x63\x75\x6d\x65\x6e\x74\x20"
+                         "\x64\x65\x73\x63\x72\x69\x62\x65"
+                         "\x73\x20\x61\x20\x63\x6f\x6d\x70"
+                         "\x72\x65\x73\x73\x69\x6f\x6e\x20"
+                         "\x6d\x65\x74\x68\x6f\x64\x20\x62"
+                         "\x61\x73\x65\x64\x20\x6f\x6e\x20"
+                         "\x74\x68\x65\x20\x4c\x5a\x4f\x2b"
+                         "\x8c\x00\x0d\x61\x6c\x67\x6f\x72"
+                         "\x69\x74\x68\x6d\x2e\x20\x20\x54"
+                         "\x68\x69\x73\x2a\x54\x01\x02\x66"
+                         "\x69\x6e\x65\x73\x94\x06\x05\x61"
+                         "\x70\x70\x6c\x69\x63\x61\x74\x76"
+                         "\x0a\x6f\x66\x88\x02\x60\x09\x27"
+                         "\xf0\x00\x0c\x20\x75\x73\x65\x64"
+                         "\x20\x69\x6e\x20\x55\x42\x49\x46"
+                         "\x53\x2e\x11\x00\x00",
+       },
+};
+
+static struct comp_testvec lzo_decomp_tv_template[] = {
+       {
+               .inlen  = 133,
+               .outlen = 159,
+               .input  = "\x00\x2b\x54\x68\x69\x73\x20\x64"
+                         "\x6f\x63\x75\x6d\x65\x6e\x74\x20"
+                         "\x64\x65\x73\x63\x72\x69\x62\x65"
+                         "\x73\x20\x61\x20\x63\x6f\x6d\x70"
+                         "\x72\x65\x73\x73\x69\x6f\x6e\x20"
+                         "\x6d\x65\x74\x68\x6f\x64\x20\x62"
+                         "\x61\x73\x65\x64\x20\x6f\x6e\x20"
+                         "\x74\x68\x65\x20\x4c\x5a\x4f\x2b"
+                         "\x8c\x00\x0d\x61\x6c\x67\x6f\x72"
+                         "\x69\x74\x68\x6d\x2e\x20\x20\x54"
+                         "\x68\x69\x73\x2a\x54\x01\x02\x66"
+                         "\x69\x6e\x65\x73\x94\x06\x05\x61"
+                         "\x70\x70\x6c\x69\x63\x61\x74\x76"
+                         "\x0a\x6f\x66\x88\x02\x60\x09\x27"
+                         "\xf0\x00\x0c\x20\x75\x73\x65\x64"
+                         "\x20\x69\x6e\x20\x55\x42\x49\x46"
+                         "\x53\x2e\x11\x00\x00",
+               .output = "This document describes a compression method based on the LZO "
+                       "compression algorithm.  This document defines the application of "
+                       "the LZO algorithm used in UBIFS.",
+       }, {
+               .inlen  = 46,
+               .outlen = 70,
+               .input  = "\x00\x0d\x4a\x6f\x69\x6e\x20\x75"
+                         "\x73\x20\x6e\x6f\x77\x20\x61\x6e"
+                         "\x64\x20\x73\x68\x61\x72\x65\x20"
+                         "\x74\x68\x65\x20\x73\x6f\x66\x74"
+                         "\x77\x70\x01\x01\x4a\x6f\x69\x6e"
+                         "\x3d\x88\x00\x11\x00\x00",
+               .output = "Join us now and share the software "
+                       "Join us now and share the software ",
+       },
+};
+
+/*
+ * Michael MIC test vectors from IEEE 802.11i
+ */
+#define MICHAEL_MIC_TEST_VECTORS 6
+
+static struct hash_testvec michael_mic_tv_template[] = {
+       {
+               .key = "\x00\x00\x00\x00\x00\x00\x00\x00",
+               .ksize = 8,
+               .plaintext = zeroed_string,
+               .psize = 0,
+               .digest = "\x82\x92\x5c\x1c\xa1\xd1\x30\xb8",
+       },
+       {
+               .key = "\x82\x92\x5c\x1c\xa1\xd1\x30\xb8",
+               .ksize = 8,
+               .plaintext = "M",
+               .psize = 1,
+               .digest = "\x43\x47\x21\xca\x40\x63\x9b\x3f",
+       },
+       {
+               .key = "\x43\x47\x21\xca\x40\x63\x9b\x3f",
+               .ksize = 8,
+               .plaintext = "Mi",
+               .psize = 2,
+               .digest = "\xe8\xf9\xbe\xca\xe9\x7e\x5d\x29",
+       },
+       {
+               .key = "\xe8\xf9\xbe\xca\xe9\x7e\x5d\x29",
+               .ksize = 8,
+               .plaintext = "Mic",
+               .psize = 3,
+               .digest = "\x90\x03\x8f\xc6\xcf\x13\xc1\xdb",
+       },
+       {
+               .key = "\x90\x03\x8f\xc6\xcf\x13\xc1\xdb",
+               .ksize = 8,
+               .plaintext = "Mich",
+               .psize = 4,
+               .digest = "\xd5\x5e\x10\x05\x10\x12\x89\x86",
+       },
+       {
+               .key = "\xd5\x5e\x10\x05\x10\x12\x89\x86",
+               .ksize = 8,
+               .plaintext = "Michael",
+               .psize = 7,
+               .digest = "\x0a\x94\x2b\x12\x4e\xca\xa5\x46",
+       }
+};
+
+/*
+ * CRC32C test vectors
+ */
+#define CRC32C_TEST_VECTORS 14
+
+static struct hash_testvec crc32c_tv_template[] = {
+       {
+               .psize = 0,
+               .digest = "\x00\x00\x00\x00",
+       },
+       {
+               .key = "\x87\xa9\xcb\xed",
+               .ksize = 4,
+               .psize = 0,
+               .digest = "\x78\x56\x34\x12",
+       },
+       {
+               .key = "\xff\xff\xff\xff",
+               .ksize = 4,
+               .plaintext = "\x01\x02\x03\x04\x05\x06\x07\x08"
+                            "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+                            "\x11\x12\x13\x14\x15\x16\x17\x18"
+                            "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
+                            "\x21\x22\x23\x24\x25\x26\x27\x28",
+               .psize = 40,
+               .digest = "\x7f\x15\x2c\x0e",
+       },
+       {
+               .key = "\xff\xff\xff\xff",
+               .ksize = 4,
+               .plaintext = "\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"
+                            "\x31\x32\x33\x34\x35\x36\x37\x38"
+                            "\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
+                            "\x41\x42\x43\x44\x45\x46\x47\x48"
+                            "\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50",
+               .psize = 40,
+               .digest = "\xf6\xeb\x80\xe9",
+       },
+       {
+               .key = "\xff\xff\xff\xff",
+               .ksize = 4,
+               .plaintext = "\x51\x52\x53\x54\x55\x56\x57\x58"
+                            "\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"
+                            "\x61\x62\x63\x64\x65\x66\x67\x68"
+                            "\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+                            "\x71\x72\x73\x74\x75\x76\x77\x78",
+               .psize = 40,
+               .digest = "\xed\xbd\x74\xde",
+       },
+       {
+               .key = "\xff\xff\xff\xff",
+               .ksize = 4,
+               .plaintext = "\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"
+                            "\x81\x82\x83\x84\x85\x86\x87\x88"
+                            "\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
+                            "\x91\x92\x93\x94\x95\x96\x97\x98"
+                            "\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0",
+               .psize = 40,
+               .digest = "\x62\xc8\x79\xd5",
+       },
+       {
+               .key = "\xff\xff\xff\xff",
+               .ksize = 4,
+               .plaintext = "\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8"
+                            "\xa9\xaa\xab\xac\xad\xae\xaf\xb0"
+                            "\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8"
+                            "\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"
+                            "\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8",
+               .psize = 40,
+               .digest = "\xd0\x9a\x97\xba",
+       },
+       {
+               .key = "\xff\xff\xff\xff",
+               .ksize = 4,
+               .plaintext = "\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0"
+                            "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8"
+                            "\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
+                            "\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8"
+                            "\xe9\xea\xeb\xec\xed\xee\xef\xf0",
+               .psize = 40,
+               .digest = "\x13\xd9\x29\x2b",
+       },
+       {
+               .key = "\x80\xea\xd3\xf1",
+               .ksize = 4,
+               .plaintext = "\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"
+                            "\x31\x32\x33\x34\x35\x36\x37\x38"
+                            "\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
+                            "\x41\x42\x43\x44\x45\x46\x47\x48"
+                            "\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50",
+               .psize = 40,
+               .digest = "\x0c\xb5\xe2\xa2",
+       },
+       {
+               .key = "\xf3\x4a\x1d\x5d",
+               .ksize = 4,
+               .plaintext = "\x51\x52\x53\x54\x55\x56\x57\x58"
+                            "\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"
+                            "\x61\x62\x63\x64\x65\x66\x67\x68"
+                            "\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+                            "\x71\x72\x73\x74\x75\x76\x77\x78",
+               .psize = 40,
+               .digest = "\xd1\x7f\xfb\xa6",
+       },
+       {
+               .key = "\x2e\x80\x04\x59",
+               .ksize = 4,
+               .plaintext = "\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"
+                            "\x81\x82\x83\x84\x85\x86\x87\x88"
+                            "\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
+                            "\x91\x92\x93\x94\x95\x96\x97\x98"
+                            "\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0",
+               .psize = 40,
+               .digest = "\x59\x33\xe6\x7a",
+       },
+       {
+               .key = "\xa6\xcc\x19\x85",
+               .ksize = 4,
+               .plaintext = "\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8"
+                            "\xa9\xaa\xab\xac\xad\xae\xaf\xb0"
+                            "\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8"
+                            "\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"
+                            "\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8",
+               .psize = 40,
+               .digest = "\xbe\x03\x01\xd2",
+       },
+       {
+               .key = "\x41\xfc\xfe\x2d",
+               .ksize = 4,
+               .plaintext = "\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0"
+                            "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8"
+                            "\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
+                            "\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8"
+                            "\xe9\xea\xeb\xec\xed\xee\xef\xf0",
+               .psize = 40,
+               .digest = "\x75\xd3\xc5\x24",
+       },
+       {
+               .key = "\xff\xff\xff\xff",
+               .ksize = 4,
+               .plaintext = "\x01\x02\x03\x04\x05\x06\x07\x08"
+                            "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+                            "\x11\x12\x13\x14\x15\x16\x17\x18"
+                            "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
+                            "\x21\x22\x23\x24\x25\x26\x27\x28"
+                            "\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"
+                            "\x31\x32\x33\x34\x35\x36\x37\x38"
+                            "\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
+                            "\x41\x42\x43\x44\x45\x46\x47\x48"
+                            "\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
+                            "\x51\x52\x53\x54\x55\x56\x57\x58"
+                            "\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"
+                            "\x61\x62\x63\x64\x65\x66\x67\x68"
+                            "\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+                            "\x71\x72\x73\x74\x75\x76\x77\x78"
+                            "\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"
+                            "\x81\x82\x83\x84\x85\x86\x87\x88"
+                            "\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
+                            "\x91\x92\x93\x94\x95\x96\x97\x98"
+                            "\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0"
+                            "\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8"
+                            "\xa9\xaa\xab\xac\xad\xae\xaf\xb0"
+                            "\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8"
+                            "\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"
+                            "\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8"
+                            "\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0"
+                            "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8"
+                            "\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
+                            "\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8"
+                            "\xe9\xea\xeb\xec\xed\xee\xef\xf0",
+               .psize = 240,
+               .digest = "\x75\xd3\xc5\x24",
+               .np = 2,
+               .tap = { 31, 209 }
+       },
+};
+
+#endif /* _CRYPTO_TESTMGR_H */
index 11c8c19f0fb7107acfd0c9189c70aeffc5dfba06..f17cd4b572f87324b2d261b491fc1f9f78d8d696 100644 (file)
@@ -663,7 +663,7 @@ config HAVE_PATA_PLATFORM
 
 config PATA_PLATFORM
        tristate "Generic platform device PATA support"
-       depends on EMBEDDED || ARCH_RPC || PPC || HAVE_PATA_PLATFORM
+       depends on EMBEDDED || PPC || HAVE_PATA_PLATFORM
        help
          This option enables support for generic directly connected ATA
          devices commonly found on embedded systems.
index 2e1a7cb2ed5f91553ef9d2a39326233197eae7bd..aeadd00411a187dc164eaa4abe4c3a447af8af59 100644 (file)
@@ -267,8 +267,8 @@ struct ahci_port_priv {
                                                 * per PM slot */
 };
 
-static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
-static int ahci_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
+static int ahci_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
+static int ahci_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
 static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc);
 static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc);
@@ -316,6 +316,7 @@ static struct device_attribute *ahci_shost_attrs[] = {
 
 static struct device_attribute *ahci_sdev_attrs[] = {
        &dev_attr_sw_activity,
+       &dev_attr_unload_heads,
        NULL
 };
 
@@ -820,10 +821,10 @@ static unsigned ahci_scr_offset(struct ata_port *ap, unsigned int sc_reg)
        return 0;
 }
 
-static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
+static int ahci_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val)
 {
-       void __iomem *port_mmio = ahci_port_base(ap);
-       int offset = ahci_scr_offset(ap, sc_reg);
+       void __iomem *port_mmio = ahci_port_base(link->ap);
+       int offset = ahci_scr_offset(link->ap, sc_reg);
 
        if (offset) {
                *val = readl(port_mmio + offset);
@@ -832,10 +833,10 @@ static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
        return -EINVAL;
 }
 
-static int ahci_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
+static int ahci_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
 {
-       void __iomem *port_mmio = ahci_port_base(ap);
-       int offset = ahci_scr_offset(ap, sc_reg);
+       void __iomem *port_mmio = ahci_port_base(link->ap);
+       int offset = ahci_scr_offset(link->ap, sc_reg);
 
        if (offset) {
                writel(val, port_mmio + offset);
@@ -973,7 +974,7 @@ static void ahci_disable_alpm(struct ata_port *ap)
        writel(PORT_IRQ_PHYRDY, port_mmio + PORT_IRQ_STAT);
 
        /* go ahead and clean out PhyRdy Change from Serror too */
-       ahci_scr_write(ap, SCR_ERROR, ((1 << 16) | (1 << 18)));
+       ahci_scr_write(&ap->link, SCR_ERROR, ((1 << 16) | (1 << 18)));
 
        /*
         * Clear flag to indicate that we should ignore all PhyRdy
@@ -1937,8 +1938,8 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
        ata_ehi_push_desc(host_ehi, "irq_stat 0x%08x", irq_stat);
 
        /* AHCI needs SError cleared; otherwise, it might lock up */
-       ahci_scr_read(ap, SCR_ERROR, &serror);
-       ahci_scr_write(ap, SCR_ERROR, serror);
+       ahci_scr_read(&ap->link, SCR_ERROR, &serror);
+       ahci_scr_write(&ap->link, SCR_ERROR, serror);
        host_ehi->serror |= serror;
 
        /* some controllers set IRQ_IF_ERR on device errors, ignore it */
@@ -2027,7 +2028,7 @@ static void ahci_port_intr(struct ata_port *ap)
        if ((hpriv->flags & AHCI_HFLAG_NO_HOTPLUG) &&
                (status & PORT_IRQ_PHYRDY)) {
                status &= ~PORT_IRQ_PHYRDY;
-               ahci_scr_write(ap, SCR_ERROR, ((1 << 16) | (1 << 18)));
+               ahci_scr_write(&ap->link, SCR_ERROR, ((1 << 16) | (1 << 18)));
        }
 
        if (unlikely(status & PORT_IRQ_ERROR)) {
index e6b4606e36b68a51448d73b755aab75d91e0fa80..e9e32ed6b1a34ccbd0e61dd846622234b07ca2f5 100644 (file)
@@ -165,8 +165,10 @@ static void piix_set_dmamode(struct ata_port *ap, struct ata_device *adev);
 static void ich_set_dmamode(struct ata_port *ap, struct ata_device *adev);
 static int ich_pata_cable_detect(struct ata_port *ap);
 static u8 piix_vmw_bmdma_status(struct ata_port *ap);
-static int piix_sidpr_scr_read(struct ata_port *ap, unsigned int reg, u32 *val);
-static int piix_sidpr_scr_write(struct ata_port *ap, unsigned int reg, u32 val);
+static int piix_sidpr_scr_read(struct ata_link *link,
+                              unsigned int reg, u32 *val);
+static int piix_sidpr_scr_write(struct ata_link *link,
+                               unsigned int reg, u32 val);
 #ifdef CONFIG_PM
 static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
 static int piix_pci_device_resume(struct pci_dev *pdev);
@@ -278,12 +280,15 @@ static const struct pci_device_id piix_pci_tbl[] = {
        /* SATA Controller IDE (PCH) */
        { 0x8086, 0x3b20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
        /* SATA Controller IDE (PCH) */
+       { 0x8086, 0x3b21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+       /* SATA Controller IDE (PCH) */
        { 0x8086, 0x3b26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
        /* SATA Controller IDE (PCH) */
+       { 0x8086, 0x3b28, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
+       /* SATA Controller IDE (PCH) */
        { 0x8086, 0x3b2d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
        /* SATA Controller IDE (PCH) */
        { 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
-
        { }     /* terminate list */
 };
 
@@ -582,6 +587,7 @@ static const struct ich_laptop ich_laptop[] = {
        { 0x27DF, 0x1025, 0x0110 },     /* ICH7 on Acer 3682WLMi */
        { 0x27DF, 0x1043, 0x1267 },     /* ICH7 on Asus W5F */
        { 0x27DF, 0x103C, 0x30A1 },     /* ICH7 on HP Compaq nc2400 */
+       { 0x27DF, 0x1071, 0xD221 },     /* ICH7 on Hercules EC-900 */
        { 0x24CA, 0x1025, 0x0061 },     /* ICH4 on ACER Aspire 2023WLMi */
        { 0x24CA, 0x1025, 0x003d },     /* ICH4 on ACER TM290 */
        { 0x266F, 0x1025, 0x0066 },     /* ICH6 on ACER Aspire 1694WLMi */
@@ -885,23 +891,9 @@ static void ich_set_dmamode(struct ata_port *ap, struct ata_device *adev)
  * Serial ATA Index/Data Pair Superset Registers access
  *
  * Beginning from ICH8, there's a sane way to access SCRs using index
- * and data register pair located at BAR5.  This creates an
- * interesting problem of mapping two SCRs to one port.
- *
- * Although they have separate SCRs, the master and slave aren't
- * independent enough to be treated as separate links - e.g. softreset
- * resets both.  Also, there's no protocol defined for hard resetting
- * singled device sharing the virtual port (no defined way to acquire
- * device signature).  This is worked around by merging the SCR values
- * into one sensible value and requesting follow-up SRST after
- * hardreset.
- *
- * SCR merging is perfomed in nibbles which is the unit contents in
- * SCRs are organized.  If two values are equal, the value is used.
- * When they differ, merge table which lists precedence of possible
- * values is consulted and the first match or the last entry when
- * nothing matches is used.  When there's no merge table for the
- * specific nibble, value from the first port is used.
+ * and data register pair located at BAR5 which means that we have
+ * separate SCRs for master and slave.  This is handled using libata
+ * slave_link facility.
  */
 static const int piix_sidx_map[] = {
        [SCR_STATUS]    = 0,
@@ -909,120 +901,38 @@ static const int piix_sidx_map[] = {
        [SCR_CONTROL]   = 1,
 };
 
-static void piix_sidpr_sel(struct ata_device *dev, unsigned int reg)
+static void piix_sidpr_sel(struct ata_link *link, unsigned int reg)
 {
-       struct ata_port *ap = dev->link->ap;
+       struct ata_port *ap = link->ap;
        struct piix_host_priv *hpriv = ap->host->private_data;
 
-       iowrite32(((ap->port_no * 2 + dev->devno) << 8) | piix_sidx_map[reg],
+       iowrite32(((ap->port_no * 2 + link->pmp) << 8) | piix_sidx_map[reg],
                  hpriv->sidpr + PIIX_SIDPR_IDX);
 }
 
-static int piix_sidpr_read(struct ata_device *dev, unsigned int reg)
-{
-       struct piix_host_priv *hpriv = dev->link->ap->host->private_data;
-
-       piix_sidpr_sel(dev, reg);
-       return ioread32(hpriv->sidpr + PIIX_SIDPR_DATA);
-}
-
-static void piix_sidpr_write(struct ata_device *dev, unsigned int reg, u32 val)
-{
-       struct piix_host_priv *hpriv = dev->link->ap->host->private_data;
-
-       piix_sidpr_sel(dev, reg);
-       iowrite32(val, hpriv->sidpr + PIIX_SIDPR_DATA);
-}
-
-static u32 piix_merge_scr(u32 val0, u32 val1, const int * const *merge_tbl)
-{
-       u32 val = 0;
-       int i, mi;
-
-       for (i = 0, mi = 0; i < 32 / 4; i++) {
-               u8 c0 = (val0 >> (i * 4)) & 0xf;
-               u8 c1 = (val1 >> (i * 4)) & 0xf;
-               u8 merged = c0;
-               const int *cur;
-
-               /* if no merge preference, assume the first value */
-               cur = merge_tbl[mi];
-               if (!cur)
-                       goto done;
-               mi++;
-
-               /* if two values equal, use it */
-               if (c0 == c1)
-                       goto done;
-
-               /* choose the first match or the last from the merge table */
-               while (*cur != -1) {
-                       if (c0 == *cur || c1 == *cur)
-                               break;
-                       cur++;
-               }
-               if (*cur == -1)
-                       cur--;
-               merged = *cur;
-       done:
-               val |= merged << (i * 4);
-       }
-
-       return val;
-}
-
-static int piix_sidpr_scr_read(struct ata_port *ap, unsigned int reg, u32 *val)
+static int piix_sidpr_scr_read(struct ata_link *link,
+                              unsigned int reg, u32 *val)
 {
-       const int * const sstatus_merge_tbl[] = {
-               /* DET */ (const int []){ 1, 3, 0, 4, 3, -1 },
-               /* SPD */ (const int []){ 2, 1, 0, -1 },
-               /* IPM */ (const int []){ 6, 2, 1, 0, -1 },
-               NULL,
-       };
-       const int * const scontrol_merge_tbl[] = {
-               /* DET */ (const int []){ 1, 0, 4, 0, -1 },
-               /* SPD */ (const int []){ 0, 2, 1, 0, -1 },
-               /* IPM */ (const int []){ 0, 1, 2, 3, 0, -1 },
-               NULL,
-       };
-       u32 v0, v1;
+       struct piix_host_priv *hpriv = link->ap->host->private_data;
 
        if (reg >= ARRAY_SIZE(piix_sidx_map))
                return -EINVAL;
 
-       if (!(ap->flags & ATA_FLAG_SLAVE_POSS)) {
-               *val = piix_sidpr_read(&ap->link.device[0], reg);
-               return 0;
-       }
-
-       v0 = piix_sidpr_read(&ap->link.device[0], reg);
-       v1 = piix_sidpr_read(&ap->link.device[1], reg);
-
-       switch (reg) {
-       case SCR_STATUS:
-               *val = piix_merge_scr(v0, v1, sstatus_merge_tbl);
-               break;
-       case SCR_ERROR:
-               *val = v0 | v1;
-               break;
-       case SCR_CONTROL:
-               *val = piix_merge_scr(v0, v1, scontrol_merge_tbl);
-               break;
-       }
-
+       piix_sidpr_sel(link, reg);
+       *val = ioread32(hpriv->sidpr + PIIX_SIDPR_DATA);
        return 0;
 }
 
-static int piix_sidpr_scr_write(struct ata_port *ap, unsigned int reg, u32 val)
+static int piix_sidpr_scr_write(struct ata_link *link,
+                               unsigned int reg, u32 val)
 {
+       struct piix_host_priv *hpriv = link->ap->host->private_data;
+
        if (reg >= ARRAY_SIZE(piix_sidx_map))
                return -EINVAL;
 
-       piix_sidpr_write(&ap->link.device[0], reg, val);
-
-       if (ap->flags & ATA_FLAG_SLAVE_POSS)
-               piix_sidpr_write(&ap->link.device[1], reg, val);
-
+       piix_sidpr_sel(link, reg);
+       iowrite32(val, hpriv->sidpr + PIIX_SIDPR_DATA);
        return 0;
 }
 
@@ -1363,28 +1273,28 @@ static const int *__devinit piix_init_sata_map(struct pci_dev *pdev,
        return map;
 }
 
-static void __devinit piix_init_sidpr(struct ata_host *host)
+static int __devinit piix_init_sidpr(struct ata_host *host)
 {
        struct pci_dev *pdev = to_pci_dev(host->dev);
        struct piix_host_priv *hpriv = host->private_data;
-       struct ata_device *dev0 = &host->ports[0]->link.device[0];
+       struct ata_link *link0 = &host->ports[0]->link;
        u32 scontrol;
-       int i;
+       int i, rc;
 
        /* check for availability */
        for (i = 0; i < 4; i++)
                if (hpriv->map[i] == IDE)
-                       return;
+                       return 0;
 
        if (!(host->ports[0]->flags & PIIX_FLAG_SIDPR))
-               return;
+               return 0;
 
        if (pci_resource_start(pdev, PIIX_SIDPR_BAR) == 0 ||
            pci_resource_len(pdev, PIIX_SIDPR_BAR) != PIIX_SIDPR_LEN)
-               return;
+               return 0;
 
        if (pcim_iomap_regions(pdev, 1 << PIIX_SIDPR_BAR, DRV_NAME))
-               return;
+               return 0;
 
        hpriv->sidpr = pcim_iomap_table(pdev)[PIIX_SIDPR_BAR];
 
@@ -1392,7 +1302,7 @@ static void __devinit piix_init_sidpr(struct ata_host *host)
         * Give it a test drive by inhibiting power save modes which
         * we'll do anyway.
         */
-       scontrol = piix_sidpr_read(dev0, SCR_CONTROL);
+       piix_sidpr_scr_read(link0, SCR_CONTROL, &scontrol);
 
        /* if IPM is already 3, SCR access is probably working.  Don't
         * un-inhibit power save modes as BIOS might have inhibited
@@ -1400,18 +1310,30 @@ static void __devinit piix_init_sidpr(struct ata_host *host)
         */
        if ((scontrol & 0xf00) != 0x300) {
                scontrol |= 0x300;
-               piix_sidpr_write(dev0, SCR_CONTROL, scontrol);
-               scontrol = piix_sidpr_read(dev0, SCR_CONTROL);
+               piix_sidpr_scr_write(link0, SCR_CONTROL, scontrol);
+               piix_sidpr_scr_read(link0, SCR_CONTROL, &scontrol);
 
                if ((scontrol & 0xf00) != 0x300) {
                        dev_printk(KERN_INFO, host->dev, "SCR access via "
                                   "SIDPR is available but doesn't work\n");
-                       return;
+                       return 0;
                }
        }
 
-       host->ports[0]->ops = &piix_sidpr_sata_ops;
-       host->ports[1]->ops = &piix_sidpr_sata_ops;
+       /* okay, SCRs available, set ops and ask libata for slave_link */
+       for (i = 0; i < 2; i++) {
+               struct ata_port *ap = host->ports[i];
+
+               ap->ops = &piix_sidpr_sata_ops;
+
+               if (ap->flags & ATA_FLAG_SLAVE_POSS) {
+                       rc = ata_slave_link_init(ap);
+                       if (rc)
+                               return rc;
+               }
+       }
+
+       return 0;
 }
 
 static void piix_iocfg_bit18_quirk(struct pci_dev *pdev)
@@ -1521,7 +1443,9 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
        /* initialize controller */
        if (port_flags & ATA_FLAG_SATA) {
                piix_init_pcs(host, piix_map_db_table[ent->driver_data]);
-               piix_init_sidpr(host);
+               rc = piix_init_sidpr(host);
+               if (rc)
+                       return rc;
        }
 
        /* apply IOCFG bit18 quirk */
index 79e3a8e7a84a36de25dea2bcb7161b7bcdcc6fd5..1ee9499bd343717ca95252a775c01d77ef3f892f 100644 (file)
@@ -163,6 +163,67 @@ MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 
 
+/*
+ * Iterator helpers.  Don't use directly.
+ *
+ * LOCKING:
+ * Host lock or EH context.
+ */
+struct ata_link *__ata_port_next_link(struct ata_port *ap,
+                                     struct ata_link *link, bool dev_only)
+{
+       /* NULL link indicates start of iteration */
+       if (!link) {
+               if (dev_only && sata_pmp_attached(ap))
+                       return ap->pmp_link;
+               return &ap->link;
+       }
+
+       /* we just iterated over the host master link, what's next? */
+       if (link == &ap->link) {
+               if (!sata_pmp_attached(ap)) {
+                       if (unlikely(ap->slave_link) && !dev_only)
+                               return ap->slave_link;
+                       return NULL;
+               }
+               return ap->pmp_link;
+       }
+
+       /* slave_link excludes PMP */
+       if (unlikely(link == ap->slave_link))
+               return NULL;
+
+       /* iterate to the next PMP link */
+       if (++link < ap->pmp_link + ap->nr_pmp_links)
+               return link;
+       return NULL;
+}
+
+/**
+ *     ata_dev_phys_link - find physical link for a device
+ *     @dev: ATA device to look up physical link for
+ *
+ *     Look up physical link which @dev is attached to.  Note that
+ *     this is different from @dev->link only when @dev is on slave
+ *     link.  For all other cases, it's the same as @dev->link.
+ *
+ *     LOCKING:
+ *     Don't care.
+ *
+ *     RETURNS:
+ *     Pointer to the found physical link.
+ */
+struct ata_link *ata_dev_phys_link(struct ata_device *dev)
+{
+       struct ata_port *ap = dev->link->ap;
+
+       if (!ap->slave_link)
+               return dev->link;
+       if (!dev->devno)
+               return &ap->link;
+       return ap->slave_link;
+}
+
 /**
  *     ata_force_cbl - force cable type according to libata.force
  *     @ap: ATA port of interest
@@ -206,7 +267,8 @@ void ata_force_cbl(struct ata_port *ap)
  *     the host link and all fan-out ports connected via PMP.  If the
  *     device part is specified as 0 (e.g. 1.00:), it specifies the
  *     first fan-out link not the host link.  Device number 15 always
- *     points to the host link whether PMP is attached or not.
+ *     points to the host link whether PMP is attached or not.  If the
+ *     controller has slave link, device number 16 points to it.
  *
  *     LOCKING:
  *     EH context.
@@ -214,12 +276,11 @@ void ata_force_cbl(struct ata_port *ap)
 static void ata_force_link_limits(struct ata_link *link)
 {
        bool did_spd = false;
-       int linkno, i;
+       int linkno = link->pmp;
+       int i;
 
        if (ata_is_host_link(link))
-               linkno = 15;
-       else
-               linkno = link->pmp;
+               linkno += 15;
 
        for (i = ata_force_tbl_size - 1; i >= 0; i--) {
                const struct ata_force_ent *fe = &ata_force_tbl[i];
@@ -266,9 +327,9 @@ static void ata_force_xfermask(struct ata_device *dev)
        int alt_devno = devno;
        int i;
 
-       /* allow n.15 for the first device attached to host port */
-       if (ata_is_host_link(dev->link) && devno == 0)
-               alt_devno = 15;
+       /* allow n.15/16 for devices attached to host port */
+       if (ata_is_host_link(dev->link))
+               alt_devno += 15;
 
        for (i = ata_force_tbl_size - 1; i >= 0; i--) {
                const struct ata_force_ent *fe = &ata_force_tbl[i];
@@ -320,9 +381,9 @@ static void ata_force_horkage(struct ata_device *dev)
        int alt_devno = devno;
        int i;
 
-       /* allow n.15 for the first device attached to host port */
-       if (ata_is_host_link(dev->link) && devno == 0)
-               alt_devno = 15;
+       /* allow n.15/16 for devices attached to host port */
+       if (ata_is_host_link(dev->link))
+               alt_devno += 15;
 
        for (i = 0; i < ata_force_tbl_size; i++) {
                const struct ata_force_ent *fe = &ata_force_tbl[i];
@@ -2681,7 +2742,7 @@ static void sata_print_link_status(struct ata_link *link)
                return;
        sata_scr_read(link, SCR_CONTROL, &scontrol);
 
-       if (ata_link_online(link)) {
+       if (ata_phys_link_online(link)) {
                tmp = (sstatus >> 4) & 0xf;
                ata_link_printk(link, KERN_INFO,
                                "SATA link up %s (SStatus %X SControl %X)\n",
@@ -3372,6 +3433,12 @@ int ata_wait_ready(struct ata_link *link, unsigned long deadline,
        unsigned long nodev_deadline = ata_deadline(start, ATA_TMOUT_FF_WAIT);
        int warned = 0;
 
+       /* Slave readiness can't be tested separately from master.  On
+        * M/S emulation configuration, this function should be called
+        * only on the master and it will handle both master and slave.
+        */
+       WARN_ON(link == link->ap->slave_link);
+
        if (time_after(nodev_deadline, deadline))
                nodev_deadline = deadline;
 
@@ -3593,7 +3660,7 @@ int ata_std_prereset(struct ata_link *link, unsigned long deadline)
        }
 
        /* no point in trying softreset on offline link */
-       if (ata_link_offline(link))
+       if (ata_phys_link_offline(link))
                ehc->i.action &= ~ATA_EH_SOFTRESET;
 
        return 0;
@@ -3671,7 +3738,7 @@ int sata_link_hardreset(struct ata_link *link, const unsigned long *timing,
        if (rc)
                goto out;
        /* if link is offline nothing more to do */
-       if (ata_link_offline(link))
+       if (ata_phys_link_offline(link))
                goto out;
 
        /* Link is online.  From this point, -ENODEV too is an error. */
@@ -4868,10 +4935,8 @@ int sata_scr_valid(struct ata_link *link)
 int sata_scr_read(struct ata_link *link, int reg, u32 *val)
 {
        if (ata_is_host_link(link)) {
-               struct ata_port *ap = link->ap;
-
                if (sata_scr_valid(link))
-                       return ap->ops->scr_read(ap, reg, val);
+                       return link->ap->ops->scr_read(link, reg, val);
                return -EOPNOTSUPP;
        }
 
@@ -4897,10 +4962,8 @@ int sata_scr_read(struct ata_link *link, int reg, u32 *val)
 int sata_scr_write(struct ata_link *link, int reg, u32 val)
 {
        if (ata_is_host_link(link)) {
-               struct ata_port *ap = link->ap;
-
                if (sata_scr_valid(link))
-                       return ap->ops->scr_write(ap, reg, val);
+                       return link->ap->ops->scr_write(link, reg, val);
                return -EOPNOTSUPP;
        }
 
@@ -4925,13 +4988,12 @@ int sata_scr_write(struct ata_link *link, int reg, u32 val)
 int sata_scr_write_flush(struct ata_link *link, int reg, u32 val)
 {
        if (ata_is_host_link(link)) {
-               struct ata_port *ap = link->ap;
                int rc;
 
                if (sata_scr_valid(link)) {
-                       rc = ap->ops->scr_write(ap, reg, val);
+                       rc = link->ap->ops->scr_write(link, reg, val);
                        if (rc == 0)
-                               rc = ap->ops->scr_read(ap, reg, &val);
+                               rc = link->ap->ops->scr_read(link, reg, &val);
                        return rc;
                }
                return -EOPNOTSUPP;
@@ -4941,7 +5003,7 @@ int sata_scr_write_flush(struct ata_link *link, int reg, u32 val)
 }
 
 /**
- *     ata_link_online - test whether the given link is online
+ *     ata_phys_link_online - test whether the given link is online
  *     @link: ATA link to test
  *
  *     Test whether @link is online.  Note that this function returns
@@ -4952,20 +5014,20 @@ int sata_scr_write_flush(struct ata_link *link, int reg, u32 val)
  *     None.
  *
  *     RETURNS:
- *     1 if the port online status is available and online.
+ *     True if the port online status is available and online.
  */
-int ata_link_online(struct ata_link *link)
+bool ata_phys_link_online(struct ata_link *link)
 {
        u32 sstatus;
 
        if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0 &&
            (sstatus & 0xf) == 0x3)
-               return 1;
-       return 0;
+               return true;
+       return false;
 }
 
 /**
- *     ata_link_offline - test whether the given link is offline
+ *     ata_phys_link_offline - test whether the given link is offline
  *     @link: ATA link to test
  *
  *     Test whether @link is offline.  Note that this function
@@ -4976,16 +5038,68 @@ int ata_link_online(struct ata_link *link)
  *     None.
  *
  *     RETURNS:
- *     1 if the port offline status is available and offline.
+ *     True if the port offline status is available and offline.
  */
-int ata_link_offline(struct ata_link *link)
+bool ata_phys_link_offline(struct ata_link *link)
 {
        u32 sstatus;
 
        if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0 &&
            (sstatus & 0xf) != 0x3)
-               return 1;
-       return 0;
+               return true;
+       return false;
+}
+
+/**
+ *     ata_link_online - test whether the given link is online
+ *     @link: ATA link to test
+ *
+ *     Test whether @link is online.  This is identical to
+ *     ata_phys_link_online() when there's no slave link.  When
+ *     there's a slave link, this function should only be called on
+ *     the master link and will return true if any of M/S links is
+ *     online.
+ *
+ *     LOCKING:
+ *     None.
+ *
+ *     RETURNS:
+ *     True if the port online status is available and online.
+ */
+bool ata_link_online(struct ata_link *link)
+{
+       struct ata_link *slave = link->ap->slave_link;
+
+       WARN_ON(link == slave); /* shouldn't be called on slave link */
+
+       return ata_phys_link_online(link) ||
+               (slave && ata_phys_link_online(slave));
+}
+
+/**
+ *     ata_link_offline - test whether the given link is offline
+ *     @link: ATA link to test
+ *
+ *     Test whether @link is offline.  This is identical to
+ *     ata_phys_link_offline() when there's no slave link.  When
+ *     there's a slave link, this function should only be called on
+ *     the master link and will return true if both M/S links are
+ *     offline.
+ *
+ *     LOCKING:
+ *     None.
+ *
+ *     RETURNS:
+ *     True if the port offline status is available and offline.
+ */
+bool ata_link_offline(struct ata_link *link)
+{
+       struct ata_link *slave = link->ap->slave_link;
+
+       WARN_ON(link == slave); /* shouldn't be called on slave link */
+
+       return ata_phys_link_offline(link) &&
+               (!slave || ata_phys_link_offline(slave));
 }
 
 #ifdef CONFIG_PM
@@ -5127,11 +5241,11 @@ int ata_port_start(struct ata_port *ap)
  */
 void ata_dev_init(struct ata_device *dev)
 {
-       struct ata_link *link = dev->link;
+       struct ata_link *link = ata_dev_phys_link(dev);
        struct ata_port *ap = link->ap;
        unsigned long flags;
 
-       /* SATA spd limit is bound to the first device */
+       /* SATA spd limit is bound to the attached device, reset together */
        link->sata_spd_limit = link->hw_sata_spd_limit;
        link->sata_spd = 0;
 
@@ -5264,6 +5378,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
        INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan);
        INIT_LIST_HEAD(&ap->eh_done_q);
        init_waitqueue_head(&ap->eh_wait_q);
+       init_completion(&ap->park_req_pending);
        init_timer_deferrable(&ap->fastdrain_timer);
        ap->fastdrain_timer.function = ata_eh_fastdrain_timerfn;
        ap->fastdrain_timer.data = (unsigned long)ap;
@@ -5294,6 +5409,7 @@ static void ata_host_release(struct device *gendev, void *res)
                        scsi_host_put(ap->scsi_host);
 
                kfree(ap->pmp_link);
+               kfree(ap->slave_link);
                kfree(ap);
                host->ports[i] = NULL;
        }
@@ -5414,6 +5530,68 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev,
        return host;
 }
 
+/**
+ *     ata_slave_link_init - initialize slave link
+ *     @ap: port to initialize slave link for
+ *
+ *     Create and initialize slave link for @ap.  This enables slave
+ *     link handling on the port.
+ *
+ *     In libata, a port contains links and a link contains devices.
+ *     There is single host link but if a PMP is attached to it,
+ *     there can be multiple fan-out links.  On SATA, there's usually
+ *     a single device connected to a link but PATA and SATA
+ *     controllers emulating TF based interface can have two - master
+ *     and slave.
+ *
+ *     However, there are a few controllers which don't fit into this
+ *     abstraction too well - SATA controllers which emulate TF
+ *     interface with both master and slave devices but also have
+ *     separate SCR register sets for each device.  These controllers
+ *     need separate links for physical link handling
+ *     (e.g. onlineness, link speed) but should be treated like a
+ *     traditional M/S controller for everything else (e.g. command
+ *     issue, softreset).
+ *
+ *     slave_link is libata's way of handling this class of
+ *     controllers without impacting core layer too much.  For
+ *     anything other than physical link handling, the default host
+ *     link is used for both master and slave.  For physical link
+ *     handling, separate @ap->slave_link is used.  All dirty details
+ *     are implemented inside libata core layer.  From LLD's POV, the
+ *     only difference is that prereset, hardreset and postreset are
+ *     called once more for the slave link, so the reset sequence
+ *     looks like the following.
+ *
+ *     prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
+ *     softreset(M) -> postreset(M) -> postreset(S)
+ *
+ *     Note that softreset is called only for the master.  Softreset
+ *     resets both M/S by definition, so SRST on master should handle
+ *     both (the standard method will work just fine).
+ *
+ *     LOCKING:
+ *     Should be called before host is registered.
+ *
+ *     RETURNS:
+ *     0 on success, -errno on failure.
+ */
+int ata_slave_link_init(struct ata_port *ap)
+{
+       struct ata_link *link;
+
+       WARN_ON(ap->slave_link);
+       WARN_ON(ap->flags & ATA_FLAG_PMP);
+
+       link = kzalloc(sizeof(*link), GFP_KERNEL);
+       if (!link)
+               return -ENOMEM;
+
+       ata_link_init(ap, link, 1);
+       ap->slave_link = link;
+       return 0;
+}
+
 static void ata_host_stop(struct device *gendev, void *res)
 {
        struct ata_host *host = dev_get_drvdata(gendev);
@@ -5640,6 +5818,8 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
 
                /* init sata_spd_limit to the current value */
                sata_link_init_spd(&ap->link);
+               if (ap->slave_link)
+                       sata_link_init_spd(ap->slave_link);
 
                /* print per-port info to dmesg */
                xfer_mask = ata_pack_xfermask(ap->pio_mask, ap->mwdma_mask,
@@ -6260,10 +6440,12 @@ EXPORT_SYMBOL_GPL(ata_base_port_ops);
 EXPORT_SYMBOL_GPL(sata_port_ops);
 EXPORT_SYMBOL_GPL(ata_dummy_port_ops);
 EXPORT_SYMBOL_GPL(ata_dummy_port_info);
+EXPORT_SYMBOL_GPL(__ata_port_next_link);
 EXPORT_SYMBOL_GPL(ata_std_bios_param);
 EXPORT_SYMBOL_GPL(ata_host_init);
 EXPORT_SYMBOL_GPL(ata_host_alloc);
 EXPORT_SYMBOL_GPL(ata_host_alloc_pinfo);
+EXPORT_SYMBOL_GPL(ata_slave_link_init);
 EXPORT_SYMBOL_GPL(ata_host_start);
 EXPORT_SYMBOL_GPL(ata_host_register);
 EXPORT_SYMBOL_GPL(ata_host_activate);
index c1db2f234d2e409d21851c91c77a292cc631406e..a93247cc395af0437ff2f88adbc2c9bac6ab5239 100644 (file)
@@ -33,6 +33,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/blkdev.h>
 #include <linux/pci.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
@@ -79,6 +80,8 @@ enum {
         */
        ATA_EH_PRERESET_TIMEOUT         = 10000,
        ATA_EH_FASTDRAIN_INTERVAL       =  3000,
+
+       ATA_EH_UA_TRIES                 = 5,
 };
 
 /* The following table determines how we sequence resets.  Each entry
@@ -457,29 +460,29 @@ static void ata_eh_clear_action(struct ata_link *link, struct ata_device *dev,
  *     RETURNS:
  *     EH_HANDLED or EH_NOT_HANDLED
  */
-enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd)
+enum blk_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd)
 {
        struct Scsi_Host *host = cmd->device->host;
        struct ata_port *ap = ata_shost_to_port(host);
        unsigned long flags;
        struct ata_queued_cmd *qc;
-       enum scsi_eh_timer_return ret;
+       enum blk_eh_timer_return ret;
 
        DPRINTK("ENTER\n");
 
        if (ap->ops->error_handler) {
-               ret = EH_NOT_HANDLED;
+               ret = BLK_EH_NOT_HANDLED;
                goto out;
        }
 
-       ret = EH_HANDLED;
+       ret = BLK_EH_HANDLED;
        spin_lock_irqsave(ap->lock, flags);
        qc = ata_qc_from_tag(ap, ap->link.active_tag);
        if (qc) {
                WARN_ON(qc->scsicmd != cmd);
                qc->flags |= ATA_QCFLAG_EH_SCHEDULED;
                qc->err_mask |= AC_ERR_TIMEOUT;
-               ret = EH_NOT_HANDLED;
+               ret = BLK_EH_NOT_HANDLED;
        }
        spin_unlock_irqrestore(ap->lock, flags);
 
@@ -831,7 +834,7 @@ void ata_qc_schedule_eh(struct ata_queued_cmd *qc)
         * Note that ATA_QCFLAG_FAILED is unconditionally set after
         * this function completes.
         */
-       scsi_req_abort_cmd(qc->scsicmd);
+       blk_abort_request(qc->scsicmd->request);
 }
 
 /**
@@ -1356,6 +1359,37 @@ static int ata_eh_read_log_10h(struct ata_device *dev,
        return 0;
 }
 
+/**
+ *     atapi_eh_tur - perform ATAPI TEST_UNIT_READY
+ *     @dev: target ATAPI device
+ *     @r_sense_key: out parameter for sense_key
+ *
+ *     Perform ATAPI TEST_UNIT_READY.
+ *
+ *     LOCKING:
+ *     EH context (may sleep).
+ *
+ *     RETURNS:
+ *     0 on success, AC_ERR_* mask on failure.
+ */
+static unsigned int atapi_eh_tur(struct ata_device *dev, u8 *r_sense_key)
+{
+       u8 cdb[ATAPI_CDB_LEN] = { TEST_UNIT_READY, 0, 0, 0, 0, 0 };
+       struct ata_taskfile tf;
+       unsigned int err_mask;
+
+       ata_tf_init(dev, &tf);
+
+       tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+       tf.command = ATA_CMD_PACKET;
+       tf.protocol = ATAPI_PROT_NODATA;
+
+       err_mask = ata_exec_internal(dev, &tf, cdb, DMA_NONE, NULL, 0, 0);
+       if (err_mask == AC_ERR_DEV)
+               *r_sense_key = tf.feature >> 4;
+       return err_mask;
+}
+
 /**
  *     atapi_eh_request_sense - perform ATAPI REQUEST_SENSE
  *     @dev: device to perform REQUEST_SENSE to
@@ -1756,7 +1790,7 @@ static unsigned int ata_eh_speed_down_verdict(struct ata_device *dev)
 static unsigned int ata_eh_speed_down(struct ata_device *dev,
                                unsigned int eflags, unsigned int err_mask)
 {
-       struct ata_link *link = dev->link;
+       struct ata_link *link = ata_dev_phys_link(dev);
        int xfer_ok = 0;
        unsigned int verdict;
        unsigned int action = 0;
@@ -1880,7 +1914,8 @@ static void ata_eh_link_autopsy(struct ata_link *link)
        for (tag = 0; tag < ATA_MAX_QUEUE; tag++) {
                struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag);
 
-               if (!(qc->flags & ATA_QCFLAG_FAILED) || qc->dev->link != link)
+               if (!(qc->flags & ATA_QCFLAG_FAILED) ||
+                   ata_dev_phys_link(qc->dev) != link)
                        continue;
 
                /* inherit upper level err_mask */
@@ -1967,6 +2002,23 @@ void ata_eh_autopsy(struct ata_port *ap)
        ata_port_for_each_link(link, ap)
                ata_eh_link_autopsy(link);
 
+       /* Handle the frigging slave link.  Autopsy is done similarly
+        * but actions and flags are transferred over to the master
+        * link and handled from there.
+        */
+       if (ap->slave_link) {
+               struct ata_eh_context *mehc = &ap->link.eh_context;
+               struct ata_eh_context *sehc = &ap->slave_link->eh_context;
+
+               ata_eh_link_autopsy(ap->slave_link);
+
+               ata_eh_about_to_do(ap->slave_link, NULL, ATA_EH_ALL_ACTIONS);
+               mehc->i.action          |= sehc->i.action;
+               mehc->i.dev_action[1]   |= sehc->i.dev_action[1];
+               mehc->i.flags           |= sehc->i.flags;
+               ata_eh_done(ap->slave_link, NULL, ATA_EH_ALL_ACTIONS);
+       }
+
        /* Autopsy of fanout ports can affect host link autopsy.
         * Perform host link autopsy last.
         */
@@ -2001,7 +2053,8 @@ static void ata_eh_link_report(struct ata_link *link)
        for (tag = 0; tag < ATA_MAX_QUEUE; tag++) {
                struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag);
 
-               if (!(qc->flags & ATA_QCFLAG_FAILED) || qc->dev->link != link ||
+               if (!(qc->flags & ATA_QCFLAG_FAILED) ||
+                   ata_dev_phys_link(qc->dev) != link ||
                    ((qc->flags & ATA_QCFLAG_QUIET) &&
                     qc->err_mask == AC_ERR_DEV))
                        continue;
@@ -2068,7 +2121,7 @@ static void ata_eh_link_report(struct ata_link *link)
                char cdb_buf[70] = "";
 
                if (!(qc->flags & ATA_QCFLAG_FAILED) ||
-                   qc->dev->link != link || !qc->err_mask)
+                   ata_dev_phys_link(qc->dev) != link || !qc->err_mask)
                        continue;
 
                if (qc->dma_dir != DMA_NONE) {
@@ -2160,12 +2213,14 @@ void ata_eh_report(struct ata_port *ap)
 }
 
 static int ata_do_reset(struct ata_link *link, ata_reset_fn_t reset,
-                       unsigned int *classes, unsigned long deadline)
+                       unsigned int *classes, unsigned long deadline,
+                       bool clear_classes)
 {
        struct ata_device *dev;
 
-       ata_link_for_each_dev(dev, link)
-               classes[dev->devno] = ATA_DEV_UNKNOWN;
+       if (clear_classes)
+               ata_link_for_each_dev(dev, link)
+                       classes[dev->devno] = ATA_DEV_UNKNOWN;
 
        return reset(link, classes, deadline);
 }
@@ -2187,17 +2242,20 @@ int ata_eh_reset(struct ata_link *link, int classify,
                 ata_reset_fn_t hardreset, ata_postreset_fn_t postreset)
 {
        struct ata_port *ap = link->ap;
+       struct ata_link *slave = ap->slave_link;
        struct ata_eh_context *ehc = &link->eh_context;
+       struct ata_eh_context *sehc = &slave->eh_context;
        unsigned int *classes = ehc->classes;
        unsigned int lflags = link->flags;
        int verbose = !(ehc->i.flags & ATA_EHI_QUIET);
        int max_tries = 0, try = 0;
+       struct ata_link *failed_link;
        struct ata_device *dev;
        unsigned long deadline, now;
        ata_reset_fn_t reset;
        unsigned long flags;
        u32 sstatus;
-       int nr_known, rc;
+       int nr_unknown, rc;
 
        /*
         * Prepare to reset
@@ -2252,8 +2310,30 @@ int ata_eh_reset(struct ata_link *link, int classify,
        }
 
        if (prereset) {
-               rc = prereset(link,
-                             ata_deadline(jiffies, ATA_EH_PRERESET_TIMEOUT));
+               unsigned long deadline = ata_deadline(jiffies,
+                                                     ATA_EH_PRERESET_TIMEOUT);
+
+               if (slave) {
+                       sehc->i.action &= ~ATA_EH_RESET;
+                       sehc->i.action |= ehc->i.action;
+               }
+
+               rc = prereset(link, deadline);
+
+               /* If present, do prereset on slave link too.  Reset
+                * is skipped iff both master and slave links report
+                * -ENOENT or clear ATA_EH_RESET.
+                */
+               if (slave && (rc == 0 || rc == -ENOENT)) {
+                       int tmp;
+
+                       tmp = prereset(slave, deadline);
+                       if (tmp != -ENOENT)
+                               rc = tmp;
+
+                       ehc->i.action |= sehc->i.action;
+               }
+
                if (rc) {
                        if (rc == -ENOENT) {
                                ata_link_printk(link, KERN_DEBUG,
@@ -2302,25 +2382,51 @@ int ata_eh_reset(struct ata_link *link, int classify,
                else
                        ehc->i.flags |= ATA_EHI_DID_SOFTRESET;
 
-               rc = ata_do_reset(link, reset, classes, deadline);
-               if (rc && rc != -EAGAIN)
+               rc = ata_do_reset(link, reset, classes, deadline, true);
+               if (rc && rc != -EAGAIN) {
+                       failed_link = link;
                        goto fail;
+               }
+
+               /* hardreset slave link if existent */
+               if (slave && reset == hardreset) {
+                       int tmp;
+
+                       if (verbose)
+                               ata_link_printk(slave, KERN_INFO,
+                                               "hard resetting link\n");
 
+                       ata_eh_about_to_do(slave, NULL, ATA_EH_RESET);
+                       tmp = ata_do_reset(slave, reset, classes, deadline,
+                                          false);
+                       switch (tmp) {
+                       case -EAGAIN:
+                               rc = -EAGAIN;
+                       case 0:
+                               break;
+                       default:
+                               failed_link = slave;
+                               rc = tmp;
+                               goto fail;
+                       }
+               }
+
+               /* perform follow-up SRST if necessary */
                if (reset == hardreset &&
                    ata_eh_followup_srst_needed(link, rc, classes)) {
-                       /* okay, let's do follow-up softreset */
                        reset = softreset;
 
                        if (!reset) {
                                ata_link_printk(link, KERN_ERR,
                                                "follow-up softreset required "
                                                "but no softreset avaliable\n");
+                               failed_link = link;
                                rc = -EINVAL;
                                goto fail;
                        }
 
                        ata_eh_about_to_do(link, NULL, ATA_EH_RESET);
-                       rc = ata_do_reset(link, reset, classes, deadline);
+                       rc = ata_do_reset(link, reset, classes, deadline, true);
                }
        } else {
                if (verbose)
@@ -2341,7 +2447,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
                dev->pio_mode = XFER_PIO_0;
                dev->flags &= ~ATA_DFLAG_SLEEPING;
 
-               if (ata_link_offline(link))
+               if (ata_phys_link_offline(ata_dev_phys_link(dev)))
                        continue;
 
                /* apply class override */
@@ -2354,6 +2460,8 @@ int ata_eh_reset(struct ata_link *link, int classify,
        /* record current link speed */
        if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0)
                link->sata_spd = (sstatus >> 4) & 0xf;
+       if (slave && sata_scr_read(slave, SCR_STATUS, &sstatus) == 0)
+               slave->sata_spd = (sstatus >> 4) & 0xf;
 
        /* thaw the port */
        if (ata_is_host_link(link))
@@ -2366,12 +2474,17 @@ int ata_eh_reset(struct ata_link *link, int classify,
         * reset and here.  This race is mediated by cross checking
         * link onlineness and classification result later.
         */
-       if (postreset)
+       if (postreset) {
                postreset(link, classes);
+               if (slave)
+                       postreset(slave, classes);
+       }
 
        /* clear cached SError */
        spin_lock_irqsave(link->ap->lock, flags);
        link->eh_info.serror = 0;
+       if (slave)
+               slave->eh_info.serror = 0;
        spin_unlock_irqrestore(link->ap->lock, flags);
 
        /* Make sure onlineness and classification result correspond.
@@ -2381,19 +2494,21 @@ int ata_eh_reset(struct ata_link *link, int classify,
         * link onlineness and classification result, those conditions
         * can be reliably detected and retried.
         */
-       nr_known = 0;
+       nr_unknown = 0;
        ata_link_for_each_dev(dev, link) {
                /* convert all ATA_DEV_UNKNOWN to ATA_DEV_NONE */
-               if (classes[dev->devno] == ATA_DEV_UNKNOWN)
+               if (classes[dev->devno] == ATA_DEV_UNKNOWN) {
                        classes[dev->devno] = ATA_DEV_NONE;
-               else
-                       nr_known++;
+                       if (ata_phys_link_online(ata_dev_phys_link(dev)))
+                               nr_unknown++;
+               }
        }
 
-       if (classify && !nr_known && ata_link_online(link)) {
+       if (classify && nr_unknown) {
                if (try < max_tries) {
                        ata_link_printk(link, KERN_WARNING, "link online but "
                                       "device misclassified, retrying\n");
+                       failed_link = link;
                        rc = -EAGAIN;
                        goto fail;
                }
@@ -2404,6 +2519,8 @@ int ata_eh_reset(struct ata_link *link, int classify,
 
        /* reset successful, schedule revalidation */
        ata_eh_done(link, NULL, ATA_EH_RESET);
+       if (slave)
+               ata_eh_done(slave, NULL, ATA_EH_RESET);
        ehc->last_reset = jiffies;
        ehc->i.action |= ATA_EH_REVALIDATE;
 
@@ -2411,6 +2528,8 @@ int ata_eh_reset(struct ata_link *link, int classify,
  out:
        /* clear hotplug flag */
        ehc->i.flags &= ~ATA_EHI_HOTPLUGGED;
+       if (slave)
+               sehc->i.flags &= ~ATA_EHI_HOTPLUGGED;
 
        spin_lock_irqsave(ap->lock, flags);
        ap->pflags &= ~ATA_PFLAG_RESETTING;
@@ -2431,7 +2550,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
        if (time_before(now, deadline)) {
                unsigned long delta = deadline - now;
 
-               ata_link_printk(link, KERN_WARNING,
+               ata_link_printk(failed_link, KERN_WARNING,
                        "reset failed (errno=%d), retrying in %u secs\n",
                        rc, DIV_ROUND_UP(jiffies_to_msecs(delta), 1000));
 
@@ -2439,13 +2558,92 @@ int ata_eh_reset(struct ata_link *link, int classify,
                        delta = schedule_timeout_uninterruptible(delta);
        }
 
-       if (rc == -EPIPE || try == max_tries - 1)
+       if (try == max_tries - 1) {
                sata_down_spd_limit(link);
+               if (slave)
+                       sata_down_spd_limit(slave);
+       } else if (rc == -EPIPE)
+               sata_down_spd_limit(failed_link);
+
        if (hardreset)
                reset = hardreset;
        goto retry;
 }
 
+static inline void ata_eh_pull_park_action(struct ata_port *ap)
+{
+       struct ata_link *link;
+       struct ata_device *dev;
+       unsigned long flags;
+
+       /*
+        * This function can be thought of as an extended version of
+        * ata_eh_about_to_do() specially crafted to accommodate the
+        * requirements of ATA_EH_PARK handling. Since the EH thread
+        * does not leave the do {} while () loop in ata_eh_recover as
+        * long as the timeout for a park request to *one* device on
+        * the port has not expired, and since we still want to pick
+        * up park requests to other devices on the same port or
+        * timeout updates for the same device, we have to pull
+        * ATA_EH_PARK actions from eh_info into eh_context.i
+        * ourselves at the beginning of each pass over the loop.
+        *
+        * Additionally, all write accesses to &ap->park_req_pending
+        * through INIT_COMPLETION() (see below) or complete_all()
+        * (see ata_scsi_park_store()) are protected by the host lock.
+        * As a result we have that park_req_pending.done is zero on
+        * exit from this function, i.e. when ATA_EH_PARK actions for
+        * *all* devices on port ap have been pulled into the
+        * respective eh_context structs. If, and only if,
+        * park_req_pending.done is non-zero by the time we reach
+        * wait_for_completion_timeout(), another ATA_EH_PARK action
+        * has been scheduled for at least one of the devices on port
+        * ap and we have to cycle over the do {} while () loop in
+        * ata_eh_recover() again.
+        */
+
+       spin_lock_irqsave(ap->lock, flags);
+       INIT_COMPLETION(ap->park_req_pending);
+       ata_port_for_each_link(link, ap) {
+               ata_link_for_each_dev(dev, link) {
+                       struct ata_eh_info *ehi = &link->eh_info;
+
+                       link->eh_context.i.dev_action[dev->devno] |=
+                               ehi->dev_action[dev->devno] & ATA_EH_PARK;
+                       ata_eh_clear_action(link, dev, ehi, ATA_EH_PARK);
+               }
+       }
+       spin_unlock_irqrestore(ap->lock, flags);
+}
+
+static void ata_eh_park_issue_cmd(struct ata_device *dev, int park)
+{
+       struct ata_eh_context *ehc = &dev->link->eh_context;
+       struct ata_taskfile tf;
+       unsigned int err_mask;
+
+       ata_tf_init(dev, &tf);
+       if (park) {
+               ehc->unloaded_mask |= 1 << dev->devno;
+               tf.command = ATA_CMD_IDLEIMMEDIATE;
+               tf.feature = 0x44;
+               tf.lbal = 0x4c;
+               tf.lbam = 0x4e;
+               tf.lbah = 0x55;
+       } else {
+               ehc->unloaded_mask &= ~(1 << dev->devno);
+               tf.command = ATA_CMD_CHK_POWER;
+       }
+
+       tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
+       tf.protocol |= ATA_PROT_NODATA;
+       err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
+       if (park && (err_mask || tf.lbal != 0xc4)) {
+               ata_dev_printk(dev, KERN_ERR, "head unload failed!\n");
+               ehc->unloaded_mask &= ~(1 << dev->devno);
+       }
+}
+
 static int ata_eh_revalidate_and_attach(struct ata_link *link,
                                        struct ata_device **r_failed_dev)
 {
@@ -2472,7 +2670,7 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link,
                if ((action & ATA_EH_REVALIDATE) && ata_dev_enabled(dev)) {
                        WARN_ON(dev->class == ATA_DEV_PMP);
 
-                       if (ata_link_offline(link)) {
+                       if (ata_phys_link_offline(ata_dev_phys_link(dev))) {
                                rc = -EIO;
                                goto err;
                        }
@@ -2610,6 +2808,53 @@ int ata_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
        return rc;
 }
 
+/**
+ *     atapi_eh_clear_ua - Clear ATAPI UNIT ATTENTION after reset
+ *     @dev: ATAPI device to clear UA for
+ *
+ *     Resets and other operations can make an ATAPI device raise
+ *     UNIT ATTENTION which causes the next operation to fail.  This
+ *     function clears UA.
+ *
+ *     LOCKING:
+ *     EH context (may sleep).
+ *
+ *     RETURNS:
+ *     0 on success, -errno on failure.
+ */
+static int atapi_eh_clear_ua(struct ata_device *dev)
+{
+       int i;
+
+       for (i = 0; i < ATA_EH_UA_TRIES; i++) {
+               u8 sense_buffer[SCSI_SENSE_BUFFERSIZE];
+               u8 sense_key = 0;
+               unsigned int err_mask;
+
+               err_mask = atapi_eh_tur(dev, &sense_key);
+               if (err_mask != 0 && err_mask != AC_ERR_DEV) {
+                       ata_dev_printk(dev, KERN_WARNING, "TEST_UNIT_READY "
+                               "failed (err_mask=0x%x)\n", err_mask);
+                       return -EIO;
+               }
+
+               if (!err_mask || sense_key != UNIT_ATTENTION)
+                       return 0;
+
+               err_mask = atapi_eh_request_sense(dev, sense_buffer, sense_key);
+               if (err_mask) {
+                       ata_dev_printk(dev, KERN_WARNING, "failed to clear "
+                               "UNIT ATTENTION (err_mask=0x%x)\n", err_mask);
+                       return -EIO;
+               }
+       }
+
+       ata_dev_printk(dev, KERN_WARNING,
+               "UNIT ATTENTION persists after %d tries\n", ATA_EH_UA_TRIES);
+
+       return 0;
+}
+
 static int ata_link_nr_enabled(struct ata_link *link)
 {
        struct ata_device *dev;
@@ -2697,7 +2942,7 @@ static int ata_eh_handle_dev_fail(struct ata_device *dev, int err)
                        /* This is the last chance, better to slow
                         * down than lose it.
                         */
-                       sata_down_spd_limit(dev->link);
+                       sata_down_spd_limit(ata_dev_phys_link(dev));
                        ata_down_xfermask_limit(dev, ATA_DNXFER_PIO);
                }
        }
@@ -2707,7 +2952,7 @@ static int ata_eh_handle_dev_fail(struct ata_device *dev, int err)
                ata_dev_disable(dev);
 
                /* detach if offline */
-               if (ata_link_offline(dev->link))
+               if (ata_phys_link_offline(ata_dev_phys_link(dev)))
                        ata_eh_detach_dev(dev);
 
                /* schedule probe if necessary */
@@ -2755,7 +3000,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
        struct ata_device *dev;
        int nr_failed_devs;
        int rc;
-       unsigned long flags;
+       unsigned long flags, deadline;
 
        DPRINTK("ENTER\n");
 
@@ -2829,6 +3074,56 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
                }
        }
 
+       do {
+               unsigned long now;
+
+               /*
+                * clears ATA_EH_PARK in eh_info and resets
+                * ap->park_req_pending
+                */
+               ata_eh_pull_park_action(ap);
+
+               deadline = jiffies;
+               ata_port_for_each_link(link, ap) {
+                       ata_link_for_each_dev(dev, link) {
+                               struct ata_eh_context *ehc = &link->eh_context;
+                               unsigned long tmp;
+
+                               if (dev->class != ATA_DEV_ATA)
+                                       continue;
+                               if (!(ehc->i.dev_action[dev->devno] &
+                                     ATA_EH_PARK))
+                                       continue;
+                               tmp = dev->unpark_deadline;
+                               if (time_before(deadline, tmp))
+                                       deadline = tmp;
+                               else if (time_before_eq(tmp, jiffies))
+                                       continue;
+                               if (ehc->unloaded_mask & (1 << dev->devno))
+                                       continue;
+
+                               ata_eh_park_issue_cmd(dev, 1);
+                       }
+               }
+
+               now = jiffies;
+               if (time_before_eq(deadline, now))
+                       break;
+
+               deadline = wait_for_completion_timeout(&ap->park_req_pending,
+                                                      deadline - now);
+       } while (deadline);
+       ata_port_for_each_link(link, ap) {
+               ata_link_for_each_dev(dev, link) {
+                       if (!(link->eh_context.unloaded_mask &
+                             (1 << dev->devno)))
+                               continue;
+
+                       ata_eh_park_issue_cmd(dev, 0);
+                       ata_eh_done(link, dev, ATA_EH_PARK);
+               }
+       }
+
        /* the rest */
        ata_port_for_each_link(link, ap) {
                struct ata_eh_context *ehc = &link->eh_context;
@@ -2852,6 +3147,20 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
                        ehc->i.flags &= ~ATA_EHI_SETMODE;
                }
 
+               /* If reset has been issued, clear UA to avoid
+                * disrupting the current users of the device.
+                */
+               if (ehc->i.flags & ATA_EHI_DID_RESET) {
+                       ata_link_for_each_dev(dev, link) {
+                               if (dev->class != ATA_DEV_ATAPI)
+                                       continue;
+                               rc = atapi_eh_clear_ua(dev);
+                               if (rc)
+                                       goto dev_fail;
+                       }
+               }
+
+               /* configure link power saving */
                if (ehc->i.action & ATA_EH_LPM)
                        ata_link_for_each_dev(dev, link)
                                ata_dev_enable_pm(dev, ap->pm_policy);
index b9d3ba423cb2d30eefc17bb349bee2376f624343..59fe051957ef327d29effc64e1865f7f5f054ddb 100644 (file)
@@ -183,6 +183,105 @@ DEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR,
                ata_scsi_lpm_show, ata_scsi_lpm_put);
 EXPORT_SYMBOL_GPL(dev_attr_link_power_management_policy);
 
+static ssize_t ata_scsi_park_show(struct device *device,
+                                 struct device_attribute *attr, char *buf)
+{
+       struct scsi_device *sdev = to_scsi_device(device);
+       struct ata_port *ap;
+       struct ata_link *link;
+       struct ata_device *dev;
+       unsigned long flags;
+       unsigned int uninitialized_var(msecs);
+       int rc = 0;
+
+       ap = ata_shost_to_port(sdev->host);
+
+       spin_lock_irqsave(ap->lock, flags);
+       dev = ata_scsi_find_dev(ap, sdev);
+       if (!dev) {
+               rc = -ENODEV;
+               goto unlock;
+       }
+       if (dev->flags & ATA_DFLAG_NO_UNLOAD) {
+               rc = -EOPNOTSUPP;
+               goto unlock;
+       }
+
+       link = dev->link;
+       if (ap->pflags & ATA_PFLAG_EH_IN_PROGRESS &&
+           link->eh_context.unloaded_mask & (1 << dev->devno) &&
+           time_after(dev->unpark_deadline, jiffies))
+               msecs = jiffies_to_msecs(dev->unpark_deadline - jiffies);
+       else
+               msecs = 0;
+
+unlock:
+       spin_unlock_irq(ap->lock);
+
+       return rc ? rc : snprintf(buf, 20, "%u\n", msecs);
+}
+
+static ssize_t ata_scsi_park_store(struct device *device,
+                                  struct device_attribute *attr,
+                                  const char *buf, size_t len)
+{
+       struct scsi_device *sdev = to_scsi_device(device);
+       struct ata_port *ap;
+       struct ata_device *dev;
+       long int input;
+       unsigned long flags;
+       int rc;
+
+       rc = strict_strtol(buf, 10, &input);
+       if (rc || input < -2)
+               return -EINVAL;
+       if (input > ATA_TMOUT_MAX_PARK) {
+               rc = -EOVERFLOW;
+               input = ATA_TMOUT_MAX_PARK;
+       }
+
+       ap = ata_shost_to_port(sdev->host);
+
+       spin_lock_irqsave(ap->lock, flags);
+       dev = ata_scsi_find_dev(ap, sdev);
+       if (unlikely(!dev)) {
+               rc = -ENODEV;
+               goto unlock;
+       }
+       if (dev->class != ATA_DEV_ATA) {
+               rc = -EOPNOTSUPP;
+               goto unlock;
+       }
+
+       if (input >= 0) {
+               if (dev->flags & ATA_DFLAG_NO_UNLOAD) {
+                       rc = -EOPNOTSUPP;
+                       goto unlock;
+               }
+
+               dev->unpark_deadline = ata_deadline(jiffies, input);
+               dev->link->eh_info.dev_action[dev->devno] |= ATA_EH_PARK;
+               ata_port_schedule_eh(ap);
+               complete(&ap->park_req_pending);
+       } else {
+               switch (input) {
+               case -1:
+                       dev->flags &= ~ATA_DFLAG_NO_UNLOAD;
+                       break;
+               case -2:
+                       dev->flags |= ATA_DFLAG_NO_UNLOAD;
+                       break;
+               }
+       }
+unlock:
+       spin_unlock_irqrestore(ap->lock, flags);
+
+       return rc ? rc : len;
+}
+DEVICE_ATTR(unload_heads, S_IRUGO | S_IWUSR,
+           ata_scsi_park_show, ata_scsi_park_store);
+EXPORT_SYMBOL_GPL(dev_attr_unload_heads);
+
 static void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq)
 {
        cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
@@ -269,6 +368,12 @@ DEVICE_ATTR(sw_activity, S_IWUGO | S_IRUGO, ata_scsi_activity_show,
                        ata_scsi_activity_store);
 EXPORT_SYMBOL_GPL(dev_attr_sw_activity);
 
+struct device_attribute *ata_common_sdev_attrs[] = {
+       &dev_attr_unload_heads,
+       NULL
+};
+EXPORT_SYMBOL_GPL(ata_common_sdev_attrs);
+
 static void ata_scsi_invalid_field(struct scsi_cmnd *cmd,
                                   void (*done)(struct scsi_cmnd *))
 {
@@ -954,6 +1059,9 @@ static int atapi_drain_needed(struct request *rq)
 static int ata_scsi_dev_config(struct scsi_device *sdev,
                               struct ata_device *dev)
 {
+       if (!ata_id_has_unload(dev->id))
+               dev->flags |= ATA_DFLAG_NO_UNLOAD;
+
        /* configure max sectors */
        blk_queue_max_sectors(sdev->request_queue, dev->max_sectors);
 
@@ -977,6 +1085,10 @@ static int ata_scsi_dev_config(struct scsi_device *sdev,
 
                blk_queue_dma_drain(q, atapi_drain_needed, buf, ATAPI_MAX_DRAIN);
        } else {
+               if (ata_id_is_ssd(dev->id))
+                       queue_flag_set_unlocked(QUEUE_FLAG_NONROT,
+                                               sdev->request_queue);
+
                /* ATA devices must be sector aligned */
                blk_queue_update_dma_alignment(sdev->request_queue,
                                               ATA_SECT_SIZE - 1);
index ade5c75b61446c75adb4174ea3c967c872c548fa..fe2839e58774f01b86b589e3aa59a9c140e0c0d2 100644 (file)
@@ -70,6 +70,7 @@ extern int atapi_passthru16;
 extern int libata_fua;
 extern int libata_noacpi;
 extern int libata_allow_tpm;
+extern struct ata_link *ata_dev_phys_link(struct ata_device *dev);
 extern void ata_force_cbl(struct ata_port *ap);
 extern u64 ata_tf_to_lba(const struct ata_taskfile *tf);
 extern u64 ata_tf_to_lba48(const struct ata_taskfile *tf);
@@ -107,6 +108,8 @@ extern void ata_qc_issue(struct ata_queued_cmd *qc);
 extern void __ata_qc_complete(struct ata_queued_cmd *qc);
 extern int atapi_check_dma(struct ata_queued_cmd *qc);
 extern void swap_buf_le16(u16 *buf, unsigned int buf_words);
+extern bool ata_phys_link_online(struct ata_link *link);
+extern bool ata_phys_link_offline(struct ata_link *link);
 extern void ata_dev_init(struct ata_device *dev);
 extern void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp);
 extern int sata_link_init_spd(struct ata_link *link);
@@ -152,7 +155,7 @@ extern int ata_bus_probe(struct ata_port *ap);
 /* libata-eh.c */
 extern unsigned long ata_internal_cmd_timeout(struct ata_device *dev, u8 cmd);
 extern void ata_internal_cmd_timed_out(struct ata_device *dev, u8 cmd);
-extern enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd);
+extern enum blk_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd);
 extern void ata_scsi_error(struct Scsi_Host *host);
 extern void ata_port_wait_eh(struct ata_port *ap);
 extern void ata_eh_fastdrain_timerfn(unsigned long arg);
index d3932901a3b3511a45e13cc489ce350392b4a0dd..1266924c11f97f7771f4ee99d232df8fbf59aae7 100644 (file)
@@ -1632,6 +1632,8 @@ static int __devinit bfin_atapi_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
+       dev_set_drvdata(&pdev->dev, host);
+
        return 0;
 }
 
@@ -1648,6 +1650,7 @@ static int __devexit bfin_atapi_remove(struct platform_device *pdev)
        struct ata_host *host = dev_get_drvdata(dev);
 
        ata_host_detach(host);
+       dev_set_drvdata(&pdev->dev, NULL);
 
        peripheral_free_list(atapi_io_port);
 
@@ -1655,27 +1658,44 @@ static int __devexit bfin_atapi_remove(struct platform_device *pdev)
 }
 
 #ifdef CONFIG_PM
-int bfin_atapi_suspend(struct platform_device *pdev, pm_message_t state)
+static int bfin_atapi_suspend(struct platform_device *pdev, pm_message_t state)
 {
-       return 0;
+       struct ata_host *host = dev_get_drvdata(&pdev->dev);
+       if (host)
+               return ata_host_suspend(host, state);
+       else
+               return 0;
 }
 
-int bfin_atapi_resume(struct platform_device *pdev)
+static int bfin_atapi_resume(struct platform_device *pdev)
 {
+       struct ata_host *host = dev_get_drvdata(&pdev->dev);
+       int ret;
+
+       if (host) {
+               ret = bfin_reset_controller(host);
+               if (ret) {
+                       printk(KERN_ERR DRV_NAME ": Error during HW init\n");
+                       return ret;
+               }
+               ata_host_resume(host);
+       }
+
        return 0;
 }
+#else
+#define bfin_atapi_suspend NULL
+#define bfin_atapi_resume NULL
 #endif
 
 static struct platform_driver bfin_atapi_driver = {
        .probe                  = bfin_atapi_probe,
        .remove                 = __devexit_p(bfin_atapi_remove),
+       .suspend                = bfin_atapi_suspend,
+       .resume                 = bfin_atapi_resume,
        .driver = {
                .name           = DRV_NAME,
                .owner          = THIS_MODULE,
-#ifdef CONFIG_PM
-               .suspend        = bfin_atapi_suspend,
-               .resume         = bfin_atapi_resume,
-#endif
        },
 };
 
index e970b227fbce39037b4f14879eb4152056df59a5..a598bb36aafc5483d4c2e7cff9edaabec691efcd 100644 (file)
@@ -230,7 +230,7 @@ static u8 sil680_init_chip(struct pci_dev *pdev, int *try_mmio)
                tmpbyte & 1, tmpbyte & 0x30);
 
        *try_mmio = 0;
-#ifdef CONFIG_PPC_MERGE
+#ifdef CONFIG_PPC
        if (machine_is(cell))
                *try_mmio = (tmpbyte & 1) || pci_resource_start(pdev, 5);
 #endif
index 3924e7209a4434ef98961ceb404bea2754451bf3..1a56db92ff7ac685bfab920508d6fcc2bc0124a1 100644 (file)
@@ -469,10 +469,10 @@ static bool sata_fsl_qc_fill_rtf(struct ata_queued_cmd *qc)
        return true;
 }
 
-static int sata_fsl_scr_write(struct ata_port *ap, unsigned int sc_reg_in,
-                              u32 val)
+static int sata_fsl_scr_write(struct ata_link *link,
+                             unsigned int sc_reg_in, u32 val)
 {
-       struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+       struct sata_fsl_host_priv *host_priv = link->ap->host->private_data;
        void __iomem *ssr_base = host_priv->ssr_base;
        unsigned int sc_reg;
 
@@ -493,10 +493,10 @@ static int sata_fsl_scr_write(struct ata_port *ap, unsigned int sc_reg_in,
        return 0;
 }
 
-static int sata_fsl_scr_read(struct ata_port *ap, unsigned int sc_reg_in,
-                       u32 *val)
+static int sata_fsl_scr_read(struct ata_link *link,
+                            unsigned int sc_reg_in, u32 *val)
 {
-       struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+       struct sata_fsl_host_priv *host_priv = link->ap->host->private_data;
        void __iomem *ssr_base = host_priv->ssr_base;
        unsigned int sc_reg;
 
@@ -645,12 +645,12 @@ static int sata_fsl_port_start(struct ata_port *ap)
         * Workaround for 8315DS board 3gbps link-up issue,
         * currently limit SATA port to GEN1 speed
         */
-       sata_fsl_scr_read(ap, SCR_CONTROL, &temp);
+       sata_fsl_scr_read(&ap->link, SCR_CONTROL, &temp);
        temp &= ~(0xF << 4);
        temp |= (0x1 << 4);
-       sata_fsl_scr_write(ap, SCR_CONTROL, temp);
+       sata_fsl_scr_write(&ap->link, SCR_CONTROL, temp);
 
-       sata_fsl_scr_read(ap, SCR_CONTROL, &temp);
+       sata_fsl_scr_read(&ap->link, SCR_CONTROL, &temp);
        dev_printk(KERN_WARNING, dev, "scr_control, speed limited to %x\n",
                        temp);
 #endif
@@ -868,7 +868,7 @@ issue_srst:
                        ioread32(CQ + hcr_base),
                        ioread32(CA + hcr_base), ioread32(CC + hcr_base));
 
-               sata_fsl_scr_read(ap, SCR_ERROR, &Serror);
+               sata_fsl_scr_read(&ap->link, SCR_ERROR, &Serror);
 
                DPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
                DPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
@@ -972,9 +972,9 @@ static void sata_fsl_error_intr(struct ata_port *ap)
         * Handle & Clear SError
         */
 
-       sata_fsl_scr_read(ap, SCR_ERROR, &SError);
+       sata_fsl_scr_read(&ap->link, SCR_ERROR, &SError);
        if (unlikely(SError & 0xFFFF0000)) {
-               sata_fsl_scr_write(ap, SCR_ERROR, SError);
+               sata_fsl_scr_write(&ap->link, SCR_ERROR, SError);
        }
 
        DPRINTK("error_intr,hStat=0x%x,CE=0x%x,DE =0x%x,SErr=0x%x\n",
@@ -1091,7 +1091,7 @@ static void sata_fsl_host_intr(struct ata_port *ap)
 
        hstatus = ioread32(hcr_base + HSTATUS);
 
-       sata_fsl_scr_read(ap, SCR_ERROR, &SError);
+       sata_fsl_scr_read(&ap->link, SCR_ERROR, &SError);
 
        if (unlikely(SError & 0xFFFF0000)) {
                DPRINTK("serror @host_intr : 0x%x\n", SError);
index 5032c32fa505f2254439c3b4940aa85f841ff220..fbbd87c96f102d9fc6c11abf5529bbd5d6eba67e 100644 (file)
@@ -269,9 +269,9 @@ static void inic_reset_port(void __iomem *port_base)
        writeb(0xff, port_base + PORT_IRQ_STAT);
 }
 
-static int inic_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val)
+static int inic_scr_read(struct ata_link *link, unsigned sc_reg, u32 *val)
 {
-       void __iomem *scr_addr = inic_port_base(ap) + PORT_SCR;
+       void __iomem *scr_addr = inic_port_base(link->ap) + PORT_SCR;
        void __iomem *addr;
 
        if (unlikely(sc_reg >= ARRAY_SIZE(scr_map)))
@@ -286,9 +286,9 @@ static int inic_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val)
        return 0;
 }
 
-static int inic_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val)
+static int inic_scr_write(struct ata_link *link, unsigned sc_reg, u32 val)
 {
-       void __iomem *scr_addr = inic_port_base(ap) + PORT_SCR;
+       void __iomem *scr_addr = inic_port_base(link->ap) + PORT_SCR;
 
        if (unlikely(sc_reg >= ARRAY_SIZE(scr_map)))
                return -EINVAL;
index c815f8ecf6e64c758eb2a43deebc5c20f259ab03..2b24ae58b52ee557e9d028e06e83de405a121a40 100644 (file)
@@ -493,10 +493,10 @@ struct mv_hw_ops {
        void (*reset_bus)(struct ata_host *host, void __iomem *mmio);
 };
 
-static int mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val);
-static int mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val);
-static int mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val);
-static int mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val);
+static int mv_scr_read(struct ata_link *link, unsigned int sc_reg_in, u32 *val);
+static int mv_scr_write(struct ata_link *link, unsigned int sc_reg_in, u32 val);
+static int mv5_scr_read(struct ata_link *link, unsigned int sc_reg_in, u32 *val);
+static int mv5_scr_write(struct ata_link *link, unsigned int sc_reg_in, u32 val);
 static int mv_port_start(struct ata_port *ap);
 static void mv_port_stop(struct ata_port *ap);
 static int mv_qc_defer(struct ata_queued_cmd *qc);
@@ -1070,23 +1070,23 @@ static unsigned int mv_scr_offset(unsigned int sc_reg_in)
        return ofs;
 }
 
-static int mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val)
+static int mv_scr_read(struct ata_link *link, unsigned int sc_reg_in, u32 *val)
 {
        unsigned int ofs = mv_scr_offset(sc_reg_in);
 
        if (ofs != 0xffffffffU) {
-               *val = readl(mv_ap_base(ap) + ofs);
+               *val = readl(mv_ap_base(link->ap) + ofs);
                return 0;
        } else
                return -EINVAL;
 }
 
-static int mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val)
+static int mv_scr_write(struct ata_link *link, unsigned int sc_reg_in, u32 val)
 {
        unsigned int ofs = mv_scr_offset(sc_reg_in);
 
        if (ofs != 0xffffffffU) {
-               writelfl(val, mv_ap_base(ap) + ofs);
+               writelfl(val, mv_ap_base(link->ap) + ofs);
                return 0;
        } else
                return -EINVAL;
@@ -2251,11 +2251,11 @@ static unsigned int mv5_scr_offset(unsigned int sc_reg_in)
        return ofs;
 }
 
-static int mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val)
+static int mv5_scr_read(struct ata_link *link, unsigned int sc_reg_in, u32 *val)
 {
-       struct mv_host_priv *hpriv = ap->host->private_data;
+       struct mv_host_priv *hpriv = link->ap->host->private_data;
        void __iomem *mmio = hpriv->base;
-       void __iomem *addr = mv5_phy_base(mmio, ap->port_no);
+       void __iomem *addr = mv5_phy_base(mmio, link->ap->port_no);
        unsigned int ofs = mv5_scr_offset(sc_reg_in);
 
        if (ofs != 0xffffffffU) {
@@ -2265,11 +2265,11 @@ static int mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val)
                return -EINVAL;
 }
 
-static int mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val)
+static int mv5_scr_write(struct ata_link *link, unsigned int sc_reg_in, u32 val)
 {
-       struct mv_host_priv *hpriv = ap->host->private_data;
+       struct mv_host_priv *hpriv = link->ap->host->private_data;
        void __iomem *mmio = hpriv->base;
-       void __iomem *addr = mv5_phy_base(mmio, ap->port_no);
+       void __iomem *addr = mv5_phy_base(mmio, link->ap->port_no);
        unsigned int ofs = mv5_scr_offset(sc_reg_in);
 
        if (ofs != 0xffffffffU) {
index 14601dc05e4162eeab2f544fd02da2738cd17db4..fae3841de0d8726468adc4b6a93202f0d4177ed7 100644 (file)
@@ -302,8 +302,8 @@ static void nv_ck804_host_stop(struct ata_host *host);
 static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance);
 static irqreturn_t nv_nf2_interrupt(int irq, void *dev_instance);
 static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance);
-static int nv_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
-static int nv_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
+static int nv_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
+static int nv_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
 
 static void nv_nf2_freeze(struct ata_port *ap);
 static void nv_nf2_thaw(struct ata_port *ap);
@@ -1511,21 +1511,21 @@ static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance)
        return ret;
 }
 
-static int nv_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
+static int nv_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val)
 {
        if (sc_reg > SCR_CONTROL)
                return -EINVAL;
 
-       *val = ioread32(ap->ioaddr.scr_addr + (sc_reg * 4));
+       *val = ioread32(link->ap->ioaddr.scr_addr + (sc_reg * 4));
        return 0;
 }
 
-static int nv_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
+static int nv_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
 {
        if (sc_reg > SCR_CONTROL)
                return -EINVAL;
 
-       iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4));
+       iowrite32(val, link->ap->ioaddr.scr_addr + (sc_reg * 4));
        return 0;
 }
 
@@ -2218,9 +2218,9 @@ static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis)
        if (!pp->qc_active)
                return;
 
-       if (ap->ops->scr_read(ap, SCR_ERROR, &serror))
+       if (ap->ops->scr_read(&ap->link, SCR_ERROR, &serror))
                return;
-       ap->ops->scr_write(ap, SCR_ERROR, serror);
+       ap->ops->scr_write(&ap->link, SCR_ERROR, serror);
 
        if (ata_stat & ATA_ERR) {
                ata_ehi_clear_desc(ehi);
index 030665ba76b73a308fd0e35693742140b761792c..750d8cdc00cd1b495eb8c40b7af5e288f18163fe 100644 (file)
@@ -137,8 +137,8 @@ struct pdc_port_priv {
        dma_addr_t              pkt_dma;
 };
 
-static int pdc_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
-static int pdc_sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
+static int pdc_sata_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
+static int pdc_sata_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
 static int pdc_ata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 static int pdc_common_port_start(struct ata_port *ap);
 static int pdc_sata_port_start(struct ata_port *ap);
@@ -386,19 +386,21 @@ static int pdc_sata_cable_detect(struct ata_port *ap)
        return ATA_CBL_SATA;
 }
 
-static int pdc_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
+static int pdc_sata_scr_read(struct ata_link *link,
+                            unsigned int sc_reg, u32 *val)
 {
        if (sc_reg > SCR_CONTROL)
                return -EINVAL;
-       *val = readl(ap->ioaddr.scr_addr + (sc_reg * 4));
+       *val = readl(link->ap->ioaddr.scr_addr + (sc_reg * 4));
        return 0;
 }
 
-static int pdc_sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
+static int pdc_sata_scr_write(struct ata_link *link,
+                             unsigned int sc_reg, u32 val)
 {
        if (sc_reg > SCR_CONTROL)
                return -EINVAL;
-       writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
+       writel(val, link->ap->ioaddr.scr_addr + (sc_reg * 4));
        return 0;
 }
 
@@ -731,7 +733,7 @@ static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc,
        if (sata_scr_valid(&ap->link)) {
                u32 serror;
 
-               pdc_sata_scr_read(ap, SCR_ERROR, &serror);
+               pdc_sata_scr_read(&ap->link, SCR_ERROR, &serror);
                ehi->serror |= serror;
        }
 
index 1600107047cf50e2d544a090c992ee52982307e8..a000c86ac859dfb2c54053cbc66a2a6875d34862 100644 (file)
@@ -111,8 +111,8 @@ struct qs_port_priv {
        qs_state_t              state;
 };
 
-static int qs_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
-static int qs_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
+static int qs_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
+static int qs_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
 static int qs_ata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 static int qs_port_start(struct ata_port *ap);
 static void qs_host_stop(struct ata_host *host);
@@ -242,11 +242,11 @@ static int qs_prereset(struct ata_link *link, unsigned long deadline)
        return ata_sff_prereset(link, deadline);
 }
 
-static int qs_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
+static int qs_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val)
 {
        if (sc_reg > SCR_CONTROL)
                return -EINVAL;
-       *val = readl(ap->ioaddr.scr_addr + (sc_reg * 8));
+       *val = readl(link->ap->ioaddr.scr_addr + (sc_reg * 8));
        return 0;
 }
 
@@ -256,11 +256,11 @@ static void qs_error_handler(struct ata_port *ap)
        ata_std_error_handler(ap);
 }
 
-static int qs_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
+static int qs_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
 {
        if (sc_reg > SCR_CONTROL)
                return -EINVAL;
-       writel(val, ap->ioaddr.scr_addr + (sc_reg * 8));
+       writel(val, link->ap->ioaddr.scr_addr + (sc_reg * 8));
        return 0;
 }
 
index 88bf4212590f06f9f3f762894b226e012e9f2b18..031d7b7dee34bc09998c9d9cfa4d65891d47aa86 100644 (file)
@@ -115,8 +115,8 @@ static int sil_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 static int sil_pci_device_resume(struct pci_dev *pdev);
 #endif
 static void sil_dev_config(struct ata_device *dev);
-static int sil_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
-static int sil_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
+static int sil_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
+static int sil_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
 static int sil_set_mode(struct ata_link *link, struct ata_device **r_failed);
 static void sil_freeze(struct ata_port *ap);
 static void sil_thaw(struct ata_port *ap);
@@ -317,9 +317,9 @@ static inline void __iomem *sil_scr_addr(struct ata_port *ap,
        return NULL;
 }
 
-static int sil_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
+static int sil_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val)
 {
-       void __iomem *mmio = sil_scr_addr(ap, sc_reg);
+       void __iomem *mmio = sil_scr_addr(link->ap, sc_reg);
 
        if (mmio) {
                *val = readl(mmio);
@@ -328,9 +328,9 @@ static int sil_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
        return -EINVAL;
 }
 
-static int sil_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
+static int sil_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
 {
-       void __iomem *mmio = sil_scr_addr(ap, sc_reg);
+       void __iomem *mmio = sil_scr_addr(link->ap, sc_reg);
 
        if (mmio) {
                writel(val, mmio);
@@ -352,8 +352,8 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
                 * controllers continue to assert IRQ as long as
                 * SError bits are pending.  Clear SError immediately.
                 */
-               sil_scr_read(ap, SCR_ERROR, &serror);
-               sil_scr_write(ap, SCR_ERROR, serror);
+               sil_scr_read(&ap->link, SCR_ERROR, &serror);
+               sil_scr_write(&ap->link, SCR_ERROR, serror);
 
                /* Sometimes spurious interrupts occur, double check
                 * it's PHYRDY CHG.
index 84ffcc26a74bec944506096c20e578a49c516bcf..4621807a1a6a1ffbc143976474141dd529f3fa7f 100644 (file)
@@ -340,8 +340,8 @@ struct sil24_port_priv {
 };
 
 static void sil24_dev_config(struct ata_device *dev);
-static int sil24_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val);
-static int sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val);
+static int sil24_scr_read(struct ata_link *link, unsigned sc_reg, u32 *val);
+static int sil24_scr_write(struct ata_link *link, unsigned sc_reg, u32 val);
 static int sil24_qc_defer(struct ata_queued_cmd *qc);
 static void sil24_qc_prep(struct ata_queued_cmd *qc);
 static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc);
@@ -504,9 +504,9 @@ static int sil24_scr_map[] = {
        [SCR_ACTIVE]    = 3,
 };
 
-static int sil24_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val)
+static int sil24_scr_read(struct ata_link *link, unsigned sc_reg, u32 *val)
 {
-       void __iomem *scr_addr = sil24_port_base(ap) + PORT_SCONTROL;
+       void __iomem *scr_addr = sil24_port_base(link->ap) + PORT_SCONTROL;
 
        if (sc_reg < ARRAY_SIZE(sil24_scr_map)) {
                void __iomem *addr;
@@ -517,9 +517,9 @@ static int sil24_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val)
        return -EINVAL;
 }
 
-static int sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val)
+static int sil24_scr_write(struct ata_link *link, unsigned sc_reg, u32 val)
 {
-       void __iomem *scr_addr = sil24_port_base(ap) + PORT_SCONTROL;
+       void __iomem *scr_addr = sil24_port_base(link->ap) + PORT_SCONTROL;
 
        if (sc_reg < ARRAY_SIZE(sil24_scr_map)) {
                void __iomem *addr;
index 1010b3069bd5164bb9ded003df2d41371c4f91c9..9c43b4e7c4a66d8d45a557141243db6aab81776e 100644 (file)
@@ -64,8 +64,8 @@ enum {
 };
 
 static int sis_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
-static int sis_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
-static int sis_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
+static int sis_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
+static int sis_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
 
 static const struct pci_device_id sis_pci_tbl[] = {
        { PCI_VDEVICE(SI, 0x0180), sis_180 },   /* SiS 964/180 */
@@ -134,10 +134,11 @@ static unsigned int get_scr_cfg_addr(struct ata_port *ap, unsigned int sc_reg)
        return addr;
 }
 
-static u32 sis_scr_cfg_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
+static u32 sis_scr_cfg_read(struct ata_link *link,
+                           unsigned int sc_reg, u32 *val)
 {
-       struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-       unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg);
+       struct pci_dev *pdev = to_pci_dev(link->ap->host->dev);
+       unsigned int cfg_addr = get_scr_cfg_addr(link->ap, sc_reg);
        u32 val2 = 0;
        u8 pmr;
 
@@ -158,10 +159,11 @@ static u32 sis_scr_cfg_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
        return 0;
 }
 
-static int sis_scr_cfg_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
+static int sis_scr_cfg_write(struct ata_link *link,
+                            unsigned int sc_reg, u32 val)
 {
-       struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-       unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg);
+       struct pci_dev *pdev = to_pci_dev(link->ap->host->dev);
+       unsigned int cfg_addr = get_scr_cfg_addr(link->ap, sc_reg);
        u8 pmr;
 
        if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */
@@ -178,8 +180,9 @@ static int sis_scr_cfg_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
        return 0;
 }
 
-static int sis_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
+static int sis_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val)
 {
+       struct ata_port *ap = link->ap;
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
        u8 pmr;
 
@@ -187,7 +190,7 @@ static int sis_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
                return -EINVAL;
 
        if (ap->flags & SIS_FLAG_CFGSCR)
-               return sis_scr_cfg_read(ap, sc_reg, val);
+               return sis_scr_cfg_read(link, sc_reg, val);
 
        pci_read_config_byte(pdev, SIS_PMR, &pmr);
 
@@ -202,8 +205,9 @@ static int sis_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
        return 0;
 }
 
-static int sis_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
+static int sis_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
 {
+       struct ata_port *ap = link->ap;
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
        u8 pmr;
 
@@ -213,7 +217,7 @@ static int sis_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
        pci_read_config_byte(pdev, SIS_PMR, &pmr);
 
        if (ap->flags & SIS_FLAG_CFGSCR)
-               return sis_scr_cfg_write(ap, sc_reg, val);
+               return sis_scr_cfg_write(link, sc_reg, val);
        else {
                iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4));
                if ((pdev->device == 0x0182) || (pdev->device == 0x0183) ||
index fb13b82aacba7ee255adbf2fef9ca7e5083654ce..609d147813ae380a5408ab5b4f268ee6b7cac811 100644 (file)
@@ -123,20 +123,22 @@ static int k2_sata_check_atapi_dma(struct ata_queued_cmd *qc)
        }
 }
 
-static int k2_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
+static int k2_sata_scr_read(struct ata_link *link,
+                           unsigned int sc_reg, u32 *val)
 {
        if (sc_reg > SCR_CONTROL)
                return -EINVAL;
-       *val = readl(ap->ioaddr.scr_addr + (sc_reg * 4));
+       *val = readl(link->ap->ioaddr.scr_addr + (sc_reg * 4));
        return 0;
 }
 
 
-static int k2_sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
+static int k2_sata_scr_write(struct ata_link *link,
+                            unsigned int sc_reg, u32 val)
 {
        if (sc_reg > SCR_CONTROL)
                return -EINVAL;
-       writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
+       writel(val, link->ap->ioaddr.scr_addr + (sc_reg * 4));
        return 0;
 }
 
index db529b8499482fc08c3f4b6de08fcc4d43a6f2cc..019575bb3e08734dfd0c531025b5dad7e47c4a63 100644 (file)
@@ -57,8 +57,8 @@ struct uli_priv {
 };
 
 static int uli_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
-static int uli_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
-static int uli_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
+static int uli_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
+static int uli_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
 
 static const struct pci_device_id uli_pci_tbl[] = {
        { PCI_VDEVICE(AL, 0x5289), uli_5289 },
@@ -107,39 +107,39 @@ static unsigned int get_scr_cfg_addr(struct ata_port *ap, unsigned int sc_reg)
        return hpriv->scr_cfg_addr[ap->port_no] + (4 * sc_reg);
 }
 
-static u32 uli_scr_cfg_read(struct ata_port *ap, unsigned int sc_reg)
+static u32 uli_scr_cfg_read(struct ata_link *link, unsigned int sc_reg)
 {
-       struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-       unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg);
+       struct pci_dev *pdev = to_pci_dev(link->ap->host->dev);
+       unsigned int cfg_addr = get_scr_cfg_addr(link->ap, sc_reg);
        u32 val;
 
        pci_read_config_dword(pdev, cfg_addr, &val);
        return val;
 }
 
-static void uli_scr_cfg_write(struct ata_port *ap, unsigned int scr, u32 val)
+static void uli_scr_cfg_write(struct ata_link *link, unsigned int scr, u32 val)
 {
-       struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-       unsigned int cfg_addr = get_scr_cfg_addr(ap, scr);
+       struct pci_dev *pdev = to_pci_dev(link->ap->host->dev);
+       unsigned int cfg_addr = get_scr_cfg_addr(link->ap, scr);
 
        pci_write_config_dword(pdev, cfg_addr, val);
 }
 
-static int uli_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
+static int uli_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val)
 {
        if (sc_reg > SCR_CONTROL)
                return -EINVAL;
 
-       *val = uli_scr_cfg_read(ap, sc_reg);
+       *val = uli_scr_cfg_read(link, sc_reg);
        return 0;
 }
 
-static int uli_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
+static int uli_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
 {
        if (sc_reg > SCR_CONTROL) //SCR_CONTROL=2, SCR_ERROR=1, SCR_STATUS=0
                return -EINVAL;
 
-       uli_scr_cfg_write(ap, sc_reg, val);
+       uli_scr_cfg_write(link, sc_reg, val);
        return 0;
 }
 
index 96deeb354e16f24918a6d76608d09b39adb0fd56..1cfa74535d91abed8d42a8c5699f9e2c30462c38 100644 (file)
@@ -68,8 +68,8 @@ enum {
 };
 
 static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
-static int svia_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
-static int svia_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
+static int svia_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
+static int svia_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
 static void svia_noop_freeze(struct ata_port *ap);
 static int vt6420_prereset(struct ata_link *link, unsigned long deadline);
 static int vt6421_pata_cable_detect(struct ata_port *ap);
@@ -152,19 +152,19 @@ MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, svia_pci_tbl);
 MODULE_VERSION(DRV_VERSION);
 
-static int svia_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
+static int svia_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val)
 {
        if (sc_reg > SCR_CONTROL)
                return -EINVAL;
-       *val = ioread32(ap->ioaddr.scr_addr + (4 * sc_reg));
+       *val = ioread32(link->ap->ioaddr.scr_addr + (4 * sc_reg));
        return 0;
 }
 
-static int svia_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
+static int svia_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
 {
        if (sc_reg > SCR_CONTROL)
                return -EINVAL;
-       iowrite32(val, ap->ioaddr.scr_addr + (4 * sc_reg));
+       iowrite32(val, link->ap->ioaddr.scr_addr + (4 * sc_reg));
        return 0;
 }
 
@@ -210,20 +210,20 @@ static int vt6420_prereset(struct ata_link *link, unsigned long deadline)
                goto skip_scr;
 
        /* Resume phy.  This is the old SATA resume sequence */
-       svia_scr_write(ap, SCR_CONTROL, 0x300);
-       svia_scr_read(ap, SCR_CONTROL, &scontrol); /* flush */
+       svia_scr_write(link, SCR_CONTROL, 0x300);
+       svia_scr_read(link, SCR_CONTROL, &scontrol); /* flush */
 
        /* wait for phy to become ready, if necessary */
        do {
                msleep(200);
-               svia_scr_read(ap, SCR_STATUS, &sstatus);
+               svia_scr_read(link, SCR_STATUS, &sstatus);
                if ((sstatus & 0xf) != 1)
                        break;
        } while (time_before(jiffies, timeout));
 
        /* open code sata_print_link_status() */
-       svia_scr_read(ap, SCR_STATUS, &sstatus);
-       svia_scr_read(ap, SCR_CONTROL, &scontrol);
+       svia_scr_read(link, SCR_STATUS, &sstatus);
+       svia_scr_read(link, SCR_CONTROL, &scontrol);
 
        online = (sstatus & 0xf) == 0x3;
 
@@ -232,7 +232,7 @@ static int vt6420_prereset(struct ata_link *link, unsigned long deadline)
                        online ? "up" : "down", sstatus, scontrol);
 
        /* SStatus is read one more time */
-       svia_scr_read(ap, SCR_STATUS, &sstatus);
+       svia_scr_read(link, SCR_STATUS, &sstatus);
 
        if (!online) {
                /* tell EH to bail */
index f3d635c0a2e9255fc51034319225208f45c446cf..c57cdff9e6bdbf21af767f70fe0ab0edc7242322 100644 (file)
@@ -98,20 +98,22 @@ enum {
                              VSC_SATA_INT_PHY_CHANGE),
 };
 
-static int vsc_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
+static int vsc_sata_scr_read(struct ata_link *link,
+                            unsigned int sc_reg, u32 *val)
 {
        if (sc_reg > SCR_CONTROL)
                return -EINVAL;
-       *val = readl(ap->ioaddr.scr_addr + (sc_reg * 4));
+       *val = readl(link->ap->ioaddr.scr_addr + (sc_reg * 4));
        return 0;
 }
 
 
-static int vsc_sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
+static int vsc_sata_scr_write(struct ata_link *link,
+                             unsigned int sc_reg, u32 val)
 {
        if (sc_reg > SCR_CONTROL)
                return -EINVAL;
-       writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
+       writel(val, link->ap->ioaddr.scr_addr + (sc_reg * 4));
        return 0;
 }
 
index 31dc0cd84afa2474c8f3a4a511e07c30ef1febe6..0a5f055dffbaa389fd8f4b2f0bfe81fe5a352241 100644 (file)
@@ -54,7 +54,7 @@ struct driver_private {
  */
 struct class_private {
        struct kset class_subsys;
-       struct list_head class_devices;
+       struct klist class_devices;
        struct list_head class_interfaces;
        struct kset class_dirs;
        struct mutex class_mutex;
index cc5e28c8885ce1b78d2b0453e9068c8abf0dde64..eb85e4312301aca04f01e4898c79b1269bc0d2a4 100644 (file)
@@ -135,6 +135,20 @@ static void remove_class_attrs(struct class *cls)
        }
 }
 
+static void klist_class_dev_get(struct klist_node *n)
+{
+       struct device *dev = container_of(n, struct device, knode_class);
+
+       get_device(dev);
+}
+
+static void klist_class_dev_put(struct klist_node *n)
+{
+       struct device *dev = container_of(n, struct device, knode_class);
+
+       put_device(dev);
+}
+
 int __class_register(struct class *cls, struct lock_class_key *key)
 {
        struct class_private *cp;
@@ -145,7 +159,7 @@ int __class_register(struct class *cls, struct lock_class_key *key)
        cp = kzalloc(sizeof(*cp), GFP_KERNEL);
        if (!cp)
                return -ENOMEM;
-       INIT_LIST_HEAD(&cp->class_devices);
+       klist_init(&cp->class_devices, klist_class_dev_get, klist_class_dev_put);
        INIT_LIST_HEAD(&cp->class_interfaces);
        kset_init(&cp->class_dirs);
        __mutex_init(&cp->class_mutex, "struct class mutex", key);
@@ -268,6 +282,71 @@ char *make_class_name(const char *name, struct kobject *kobj)
 }
 #endif
 
+/**
+ * class_dev_iter_init - initialize class device iterator
+ * @iter: class iterator to initialize
+ * @class: the class we wanna iterate over
+ * @start: the device to start iterating from, if any
+ * @type: device_type of the devices to iterate over, NULL for all
+ *
+ * Initialize class iterator @iter such that it iterates over devices
+ * of @class.  If @start is set, the list iteration will start there,
+ * otherwise if it is NULL, the iteration starts at the beginning of
+ * the list.
+ */
+void class_dev_iter_init(struct class_dev_iter *iter, struct class *class,
+                        struct device *start, const struct device_type *type)
+{
+       struct klist_node *start_knode = NULL;
+
+       if (start)
+               start_knode = &start->knode_class;
+       klist_iter_init_node(&class->p->class_devices, &iter->ki, start_knode);
+       iter->type = type;
+}
+EXPORT_SYMBOL_GPL(class_dev_iter_init);
+
+/**
+ * class_dev_iter_next - iterate to the next device
+ * @iter: class iterator to proceed
+ *
+ * Proceed @iter to the next device and return it.  Returns NULL if
+ * iteration is complete.
+ *
+ * The returned device is referenced and won't be released till
+ * iterator is proceed to the next device or exited.  The caller is
+ * free to do whatever it wants to do with the device including
+ * calling back into class code.
+ */
+struct device *class_dev_iter_next(struct class_dev_iter *iter)
+{
+       struct klist_node *knode;
+       struct device *dev;
+
+       while (1) {
+               knode = klist_next(&iter->ki);
+               if (!knode)
+                       return NULL;
+               dev = container_of(knode, struct device, knode_class);
+               if (!iter->type || iter->type == dev->type)
+                       return dev;
+       }
+}
+EXPORT_SYMBOL_GPL(class_dev_iter_next);
+
+/**
+ * class_dev_iter_exit - finish iteration
+ * @iter: class iterator to finish
+ *
+ * Finish an iteration.  Always call this function after iteration is
+ * complete whether the iteration ran till the end or not.
+ */
+void class_dev_iter_exit(struct class_dev_iter *iter)
+{
+       klist_iter_exit(&iter->ki);
+}
+EXPORT_SYMBOL_GPL(class_dev_iter_exit);
+
 /**
  * class_for_each_device - device iterator
  * @class: the class we're iterating
@@ -283,13 +362,13 @@ char *make_class_name(const char *name, struct kobject *kobj)
  * We check the return of @fn each time. If it returns anything
  * other than 0, we break out and return that value.
  *
- * Note, we hold class->class_mutex in this function, so it can not be
- * re-acquired in @fn, otherwise it will self-deadlocking. For
- * example, calls to add or remove class members would be verboten.
+ * @fn is allowed to do anything including calling back into class
+ * code.  There's no locking restriction.
  */
 int class_for_each_device(struct class *class, struct device *start,
                          void *data, int (*fn)(struct device *, void *))
 {
+       struct class_dev_iter iter;
        struct device *dev;
        int error = 0;
 
@@ -301,20 +380,13 @@ int class_for_each_device(struct class *class, struct device *start,
                return -EINVAL;
        }
 
-       mutex_lock(&class->p->class_mutex);
-       list_for_each_entry(dev, &class->p->class_devices, node) {
-               if (start) {
-                       if (start == dev)
-                               start = NULL;
-                       continue;
-               }
-               dev = get_device(dev);
+       class_dev_iter_init(&iter, class, start, NULL);
+       while ((dev = class_dev_iter_next(&iter))) {
                error = fn(dev, data);
-               put_device(dev);
                if (error)
                        break;
        }
-       mutex_unlock(&class->p->class_mutex);
+       class_dev_iter_exit(&iter);
 
        return error;
 }
@@ -337,16 +409,15 @@ EXPORT_SYMBOL_GPL(class_for_each_device);
  *
  * Note, you will need to drop the reference with put_device() after use.
  *
- * We hold class->class_mutex in this function, so it can not be
- * re-acquired in @match, otherwise it will self-deadlocking. For
- * example, calls to add or remove class members would be verboten.
+ * @fn is allowed to do anything including calling back into class
+ * code.  There's no locking restriction.
  */
 struct device *class_find_device(struct class *class, struct device *start,
                                 void *data,
                                 int (*match)(struct device *, void *))
 {
+       struct class_dev_iter iter;
        struct device *dev;
-       int found = 0;
 
        if (!class)
                return NULL;
@@ -356,29 +427,23 @@ struct device *class_find_device(struct class *class, struct device *start,
                return NULL;
        }
 
-       mutex_lock(&class->p->class_mutex);
-       list_for_each_entry(dev, &class->p->class_devices, node) {
-               if (start) {
-                       if (start == dev)
-                               start = NULL;
-                       continue;
-               }
-               dev = get_device(dev);
+       class_dev_iter_init(&iter, class, start, NULL);
+       while ((dev = class_dev_iter_next(&iter))) {
                if (match(dev, data)) {
-                       found = 1;
+                       get_device(dev);
                        break;
-               } else
-                       put_device(dev);
+               }
        }
-       mutex_unlock(&class->p->class_mutex);
+       class_dev_iter_exit(&iter);
 
-       return found ? dev : NULL;
+       return dev;
 }
 EXPORT_SYMBOL_GPL(class_find_device);
 
 int class_interface_register(struct class_interface *class_intf)
 {
        struct class *parent;
+       struct class_dev_iter iter;
        struct device *dev;
 
        if (!class_intf || !class_intf->class)
@@ -391,8 +456,10 @@ int class_interface_register(struct class_interface *class_intf)
        mutex_lock(&parent->p->class_mutex);
        list_add_tail(&class_intf->node, &parent->p->class_interfaces);
        if (class_intf->add_dev) {
-               list_for_each_entry(dev, &parent->p->class_devices, node)
+               class_dev_iter_init(&iter, parent, NULL, NULL);
+               while ((dev = class_dev_iter_next(&iter)))
                        class_intf->add_dev(dev, class_intf);
+               class_dev_iter_exit(&iter);
        }
        mutex_unlock(&parent->p->class_mutex);
 
@@ -402,6 +469,7 @@ int class_interface_register(struct class_interface *class_intf)
 void class_interface_unregister(struct class_interface *class_intf)
 {
        struct class *parent = class_intf->class;
+       struct class_dev_iter iter;
        struct device *dev;
 
        if (!parent)
@@ -410,8 +478,10 @@ void class_interface_unregister(struct class_interface *class_intf)
        mutex_lock(&parent->p->class_mutex);
        list_del_init(&class_intf->node);
        if (class_intf->remove_dev) {
-               list_for_each_entry(dev, &parent->p->class_devices, node)
+               class_dev_iter_init(&iter, parent, NULL, NULL);
+               while ((dev = class_dev_iter_next(&iter)))
                        class_intf->remove_dev(dev, class_intf);
+               class_dev_iter_exit(&iter);
        }
        mutex_unlock(&parent->p->class_mutex);
 
index d021c98605b3a1fe7e7dcd5f61e9e456b2a16aae..b98cb1416a2d7a8a74dd5f64e4d1f1abcc35fbf2 100644 (file)
@@ -536,7 +536,6 @@ void device_initialize(struct device *dev)
        klist_init(&dev->klist_children, klist_children_get,
                   klist_children_put);
        INIT_LIST_HEAD(&dev->dma_pools);
-       INIT_LIST_HEAD(&dev->node);
        init_MUTEX(&dev->sem);
        spin_lock_init(&dev->devres_lock);
        INIT_LIST_HEAD(&dev->devres_head);
@@ -916,7 +915,8 @@ int device_add(struct device *dev)
        if (dev->class) {
                mutex_lock(&dev->class->p->class_mutex);
                /* tie the class to the device */
-               list_add_tail(&dev->node, &dev->class->p->class_devices);
+               klist_add_tail(&dev->knode_class,
+                              &dev->class->p->class_devices);
 
                /* notify any interfaces that the device is here */
                list_for_each_entry(class_intf,
@@ -1032,7 +1032,7 @@ void device_del(struct device *dev)
                        if (class_intf->remove_dev)
                                class_intf->remove_dev(dev, class_intf);
                /* remove the device from the class list */
-               list_del_init(&dev->node);
+               klist_del(&dev->knode_class);
                mutex_unlock(&dev->class->p->class_mutex);
        }
        device_remove_file(dev, &uevent_attr);
index 0c39782b26600f5d89d83e3f38c964aac9a28fbd..aa69556c34857bddb120fdb8f378afa6fff8adaa 100644 (file)
@@ -109,12 +109,12 @@ static const struct attribute_group attr_group = {
 static int
 aoedisk_add_sysfs(struct aoedev *d)
 {
-       return sysfs_create_group(&d->gd->dev.kobj, &attr_group);
+       return sysfs_create_group(&disk_to_dev(d->gd)->kobj, &attr_group);
 }
 void
 aoedisk_rm_sysfs(struct aoedev *d)
 {
-       sysfs_remove_group(&d->gd->dev.kobj, &attr_group);
+       sysfs_remove_group(&disk_to_dev(d->gd)->kobj, &attr_group);
 }
 
 static int
@@ -276,7 +276,7 @@ aoeblk_gdalloc(void *vp)
        gd->first_minor = d->sysminor * AOE_PARTITIONS;
        gd->fops = &aoe_bdops;
        gd->private_data = d;
-       gd->capacity = d->ssize;
+       set_capacity(gd, d->ssize);
        snprintf(gd->disk_name, sizeof gd->disk_name, "etherd/e%ld.%d",
                d->aoemajor, d->aoeminor);
 
index 2f1746295d06fc438ac4b1ba923c2aeb1d634dd8..961d29a53cab5461a1421d1b236fdccdb43d52e6 100644 (file)
@@ -645,7 +645,7 @@ aoecmd_sleepwork(struct work_struct *work)
                unsigned long flags;
                u64 ssize;
 
-               ssize = d->gd->capacity;
+               ssize = get_capacity(d->gd);
                bd = bdget_disk(d->gd, 0);
 
                if (bd) {
@@ -707,7 +707,7 @@ ataid_complete(struct aoedev *d, struct aoetgt *t, unsigned char *id)
        if (d->flags & (DEVFL_GDALLOC|DEVFL_NEWSIZE))
                return;
        if (d->gd != NULL) {
-               d->gd->capacity = ssize;
+               set_capacity(d->gd, ssize);
                d->flags |= DEVFL_NEWSIZE;
        } else
                d->flags |= DEVFL_GDALLOC;
@@ -756,12 +756,17 @@ diskstats(struct gendisk *disk, struct bio *bio, ulong duration, sector_t sector
        unsigned long n_sect = bio->bi_size >> 9;
        const int rw = bio_data_dir(bio);
        struct hd_struct *part;
+       int cpu;
 
-       part = get_part(disk, sector);
-       all_stat_inc(disk, part, ios[rw], sector);
-       all_stat_add(disk, part, ticks[rw], duration, sector);
-       all_stat_add(disk, part, sectors[rw], n_sect, sector);
-       all_stat_add(disk, part, io_ticks, duration, sector);
+       cpu = part_stat_lock();
+       part = disk_map_sector_rcu(disk, sector);
+
+       part_stat_inc(cpu, part, ios[rw]);
+       part_stat_add(cpu, part, ticks[rw], duration);
+       part_stat_add(cpu, part, sectors[rw], n_sect);
+       part_stat_add(cpu, part, io_ticks, duration);
+
+       part_stat_unlock();
 }
 
 void
index a1d813ab0d6b6046b7d1a1e34ac3d60fd4b68179..6a8038d115b5948805e2f18a7b6d0a6b90f7e583 100644 (file)
@@ -91,7 +91,7 @@ aoedev_downdev(struct aoedev *d)
        }
 
        if (d->gd)
-               d->gd->capacity = 0;
+               set_capacity(d->gd, 0);
 
        d->flags &= ~DEVFL_UP;
 }
index b73116ef92364e7993fba3c4bd2c5d164e2e6f1a..1e1f9153000c27638e854142017fc61f6b49a094 100644 (file)
@@ -3460,8 +3460,8 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
               hba[i]->intr[SIMPLE_MODE_INT], dac ? "" : " not");
 
        hba[i]->cmd_pool_bits =
-           kmalloc(((hba[i]->nr_cmds + BITS_PER_LONG -
-                     1) / BITS_PER_LONG) * sizeof(unsigned long), GFP_KERNEL);
+           kmalloc(DIV_ROUND_UP(hba[i]->nr_cmds, BITS_PER_LONG)
+                       * sizeof(unsigned long), GFP_KERNEL);
        hba[i]->cmd_pool = (CommandList_struct *)
            pci_alloc_consistent(hba[i]->pdev,
                    hba[i]->nr_cmds * sizeof(CommandList_struct),
@@ -3493,8 +3493,8 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
        /* command and error info recs zeroed out before
           they are used */
        memset(hba[i]->cmd_pool_bits, 0,
-              ((hba[i]->nr_cmds + BITS_PER_LONG -
-                1) / BITS_PER_LONG) * sizeof(unsigned long));
+              DIV_ROUND_UP(hba[i]->nr_cmds, BITS_PER_LONG)
+                       * sizeof(unsigned long));
 
        hba[i]->num_luns = 0;
        hba[i]->highest_lun = -1;
index e1233aabda771493718b5f37f9228e00301098e3..a3fd87b414444a7f094643a6047f25c1f0118a13 100644 (file)
@@ -365,7 +365,7 @@ struct scsi2map {
 
 static int 
 cciss_scsi_add_entry(int ctlr, int hostno, 
-               unsigned char *scsi3addr, int devtype,
+               struct cciss_scsi_dev_t *device,
                struct scsi2map *added, int *nadded)
 {
        /* assumes hba[ctlr]->scsi_ctlr->lock is held */ 
@@ -384,12 +384,12 @@ cciss_scsi_add_entry(int ctlr, int hostno,
        lun = 0;
        /* Is this device a non-zero lun of a multi-lun device */
        /* byte 4 of the 8-byte LUN addr will contain the logical unit no. */
-       if (scsi3addr[4] != 0) {
+       if (device->scsi3addr[4] != 0) {
                /* Search through our list and find the device which */
                /* has the same 8 byte LUN address, excepting byte 4. */
                /* Assign the same bus and target for this new LUN. */
                /* Use the logical unit number from the firmware. */
-               memcpy(addr1, scsi3addr, 8);
+               memcpy(addr1, device->scsi3addr, 8);
                addr1[4] = 0;
                for (i = 0; i < n; i++) {
                        sd = &ccissscsi[ctlr].dev[i];
@@ -399,7 +399,7 @@ cciss_scsi_add_entry(int ctlr, int hostno,
                        if (memcmp(addr1, addr2, 8) == 0) {
                                bus = sd->bus;
                                target = sd->target;
-                               lun = scsi3addr[4];
+                               lun = device->scsi3addr[4];
                                break;
                        }
                }
@@ -420,8 +420,12 @@ cciss_scsi_add_entry(int ctlr, int hostno,
        added[*nadded].lun = sd->lun;
        (*nadded)++;
 
-       memcpy(&sd->scsi3addr[0], scsi3addr, 8);
-       sd->devtype = devtype;
+       memcpy(sd->scsi3addr, device->scsi3addr, 8);
+       memcpy(sd->vendor, device->vendor, sizeof(sd->vendor));
+       memcpy(sd->revision, device->revision, sizeof(sd->revision));
+       memcpy(sd->device_id, device->device_id, sizeof(sd->device_id));
+       sd->devtype = device->devtype;
+
        ccissscsi[ctlr].ndevices++;
 
        /* initially, (before registering with scsi layer) we don't 
@@ -487,6 +491,22 @@ static void fixup_botched_add(int ctlr, char *scsi3addr)
        CPQ_TAPE_UNLOCK(ctlr, flags);
 }
 
+static int device_is_the_same(struct cciss_scsi_dev_t *dev1,
+       struct cciss_scsi_dev_t *dev2)
+{
+       return dev1->devtype == dev2->devtype &&
+               memcmp(dev1->scsi3addr, dev2->scsi3addr,
+                       sizeof(dev1->scsi3addr)) == 0 &&
+               memcmp(dev1->device_id, dev2->device_id,
+                       sizeof(dev1->device_id)) == 0 &&
+               memcmp(dev1->vendor, dev2->vendor,
+                       sizeof(dev1->vendor)) == 0 &&
+               memcmp(dev1->model, dev2->model,
+                       sizeof(dev1->model)) == 0 &&
+               memcmp(dev1->revision, dev2->revision,
+                       sizeof(dev1->revision)) == 0;
+}
+
 static int
 adjust_cciss_scsi_table(int ctlr, int hostno,
        struct cciss_scsi_dev_t sd[], int nsds)
@@ -532,7 +552,7 @@ adjust_cciss_scsi_table(int ctlr, int hostno,
                for (j=0;j<nsds;j++) {
                        if (SCSI3ADDR_EQ(sd[j].scsi3addr,
                                csd->scsi3addr)) {
-                               if (sd[j].devtype == csd->devtype)
+                               if (device_is_the_same(&sd[j], csd))
                                        found=2;
                                else
                                        found=1;
@@ -548,22 +568,26 @@ adjust_cciss_scsi_table(int ctlr, int hostno,
                        cciss_scsi_remove_entry(ctlr, hostno, i,
                                removed, &nremoved);
                        /* remove ^^^, hence i not incremented */
-               } 
-               else if (found == 1) { /* device is different kind */
+               } else if (found == 1) { /* device is different in some way */
                        changes++;
-                       printk("cciss%d: device c%db%dt%dl%d type changed "
-                               "(device type now %s).\n",
-                               ctlr, hostno, csd->bus, csd->target, csd->lun,
-                                       scsi_device_type(csd->devtype));
+                       printk("cciss%d: device c%db%dt%dl%d has changed.\n",
+                               ctlr, hostno, csd->bus, csd->target, csd->lun);
                        cciss_scsi_remove_entry(ctlr, hostno, i,
                                removed, &nremoved);
                        /* remove ^^^, hence i not incremented */
-                       if (cciss_scsi_add_entry(ctlr, hostno,
-                               &sd[j].scsi3addr[0], sd[j].devtype,
+                       if (cciss_scsi_add_entry(ctlr, hostno, &sd[j],
                                added, &nadded) != 0)
                                /* we just removed one, so add can't fail. */
                                        BUG();
                        csd->devtype = sd[j].devtype;
+                       memcpy(csd->device_id, sd[j].device_id,
+                               sizeof(csd->device_id));
+                       memcpy(csd->vendor, sd[j].vendor,
+                               sizeof(csd->vendor));
+                       memcpy(csd->model, sd[j].model,
+                               sizeof(csd->model));
+                       memcpy(csd->revision, sd[j].revision,
+                               sizeof(csd->revision));
                } else          /* device is same as it ever was, */
                        i++;    /* so just move along. */
        }
@@ -577,7 +601,7 @@ adjust_cciss_scsi_table(int ctlr, int hostno,
                        csd = &ccissscsi[ctlr].dev[j];
                        if (SCSI3ADDR_EQ(sd[i].scsi3addr,
                                csd->scsi3addr)) {
-                               if (sd[i].devtype == csd->devtype)
+                               if (device_is_the_same(&sd[i], csd))
                                        found=2;        /* found device */
                                else
                                        found=1;        /* found a bug. */
@@ -586,16 +610,14 @@ adjust_cciss_scsi_table(int ctlr, int hostno,
                }
                if (!found) {
                        changes++;
-                       if (cciss_scsi_add_entry(ctlr, hostno, 
-
-                               &sd[i].scsi3addr[0], sd[i].devtype,
+                       if (cciss_scsi_add_entry(ctlr, hostno, &sd[i],
                                added, &nadded) != 0)
                                break;
                } else if (found == 1) {
                        /* should never happen... */
                        changes++;
-                       printk("cciss%d: device unexpectedly changed type\n",
-                               ctlr);
+                       printk(KERN_WARNING "cciss%d: device "
+                               "unexpectedly changed\n", ctlr);
                        /* but if it does happen, we just ignore that device */
                }
        }
@@ -1012,7 +1034,8 @@ cciss_scsi_interpret_error(CommandList_struct *cp)
 
 static int
 cciss_scsi_do_inquiry(ctlr_info_t *c, unsigned char *scsi3addr, 
-                unsigned char *buf, unsigned char bufsize)
+       unsigned char page, unsigned char *buf,
+       unsigned char bufsize)
 {
        int rc;
        CommandList_struct *cp;
@@ -1032,8 +1055,8 @@ cciss_scsi_do_inquiry(ctlr_info_t *c, unsigned char *scsi3addr,
        ei = cp->err_info; 
 
        cdb[0] = CISS_INQUIRY;
-       cdb[1] = 0;
-       cdb[2] = 0;
+       cdb[1] = (page != 0);
+       cdb[2] = page;
        cdb[3] = 0;
        cdb[4] = bufsize;
        cdb[5] = 0;
@@ -1053,6 +1076,25 @@ cciss_scsi_do_inquiry(ctlr_info_t *c, unsigned char *scsi3addr,
        return rc;      
 }
 
+/* Get the device id from inquiry page 0x83 */
+static int cciss_scsi_get_device_id(ctlr_info_t *c, unsigned char *scsi3addr,
+       unsigned char *device_id, int buflen)
+{
+       int rc;
+       unsigned char *buf;
+
+       if (buflen > 16)
+               buflen = 16;
+       buf = kzalloc(64, GFP_KERNEL);
+       if (!buf)
+               return -1;
+       rc = cciss_scsi_do_inquiry(c, scsi3addr, 0x83, buf, 64);
+       if (rc == 0)
+               memcpy(device_id, &buf[8], buflen);
+       kfree(buf);
+       return rc != 0;
+}
+
 static int
 cciss_scsi_do_report_phys_luns(ctlr_info_t *c, 
                ReportLunData_struct *buf, int bufsize)
@@ -1142,25 +1184,21 @@ cciss_update_non_disk_devices(int cntl_num, int hostno)
        ctlr_info_t *c;
        __u32 num_luns=0;
        unsigned char *ch;
-       /* unsigned char found[CCISS_MAX_SCSI_DEVS_PER_HBA]; */
-       struct cciss_scsi_dev_t currentsd[CCISS_MAX_SCSI_DEVS_PER_HBA];
+       struct cciss_scsi_dev_t *currentsd, *this_device;
        int ncurrent=0;
        int reportlunsize = sizeof(*ld_buff) + CISS_MAX_PHYS_LUN * 8;
        int i;
 
        c = (ctlr_info_t *) hba[cntl_num];      
        ld_buff = kzalloc(reportlunsize, GFP_KERNEL);
-       if (ld_buff == NULL) {
-               printk(KERN_ERR "cciss: out of memory\n");
-               return;
-       }
        inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL);
-        if (inq_buff == NULL) {
-                printk(KERN_ERR "cciss: out of memory\n");
-                kfree(ld_buff);
-                return;
+       currentsd = kzalloc(sizeof(*currentsd) *
+                       (CCISS_MAX_SCSI_DEVS_PER_HBA+1), GFP_KERNEL);
+       if (ld_buff == NULL || inq_buff == NULL || currentsd == NULL) {
+               printk(KERN_ERR "cciss: out of memory\n");
+               goto out;
        }
-
+       this_device = &currentsd[CCISS_MAX_SCSI_DEVS_PER_HBA];
        if (cciss_scsi_do_report_phys_luns(c, ld_buff, reportlunsize) == 0) {
                ch = &ld_buff->LUNListLength[0];
                num_luns = ((ch[0]<<24) | (ch[1]<<16) | (ch[2]<<8) | ch[3]) / 8;
@@ -1179,23 +1217,34 @@ cciss_update_non_disk_devices(int cntl_num, int hostno)
 
 
        /* adjust our table of devices */       
-       for(i=0; i<num_luns; i++)
-       {
-               int devtype;
-
+       for (i = 0; i < num_luns; i++) {
                /* for each physical lun, do an inquiry */
                if (ld_buff->LUN[i][3] & 0xC0) continue;
                memset(inq_buff, 0, OBDR_TAPE_INQ_SIZE);
                memcpy(&scsi3addr[0], &ld_buff->LUN[i][0], 8);
 
-               if (cciss_scsi_do_inquiry(hba[cntl_num], scsi3addr, inq_buff,
-                       (unsigned char) OBDR_TAPE_INQ_SIZE) != 0) {
+               if (cciss_scsi_do_inquiry(hba[cntl_num], scsi3addr, 0, inq_buff,
+                       (unsigned char) OBDR_TAPE_INQ_SIZE) != 0)
                        /* Inquiry failed (msg printed already) */
-                       devtype = 0; /* so we will skip this device. */
-               } else /* what kind of device is this? */
-                       devtype = (inq_buff[0] & 0x1f);
-
-               switch (devtype)
+                       continue; /* so we will skip this device. */
+
+               this_device->devtype = (inq_buff[0] & 0x1f);
+               this_device->bus = -1;
+               this_device->target = -1;
+               this_device->lun = -1;
+               memcpy(this_device->scsi3addr, scsi3addr, 8);
+               memcpy(this_device->vendor, &inq_buff[8],
+                       sizeof(this_device->vendor));
+               memcpy(this_device->model, &inq_buff[16],
+                       sizeof(this_device->model));
+               memcpy(this_device->revision, &inq_buff[32],
+                       sizeof(this_device->revision));
+               memset(this_device->device_id, 0,
+                       sizeof(this_device->device_id));
+               cciss_scsi_get_device_id(hba[cntl_num], scsi3addr,
+                       this_device->device_id, sizeof(this_device->device_id));
+
+               switch (this_device->devtype)
                {
                  case 0x05: /* CD-ROM */ {
 
@@ -1220,15 +1269,10 @@ cciss_update_non_disk_devices(int cntl_num, int hostno)
                        if (ncurrent >= CCISS_MAX_SCSI_DEVS_PER_HBA) {
                                printk(KERN_INFO "cciss%d: %s ignored, "
                                        "too many devices.\n", cntl_num,
-                                       scsi_device_type(devtype));
+                                       scsi_device_type(this_device->devtype));
                                break;
                        }
-                       memcpy(&currentsd[ncurrent].scsi3addr[0], 
-                               &scsi3addr[0], 8);
-                       currentsd[ncurrent].devtype = devtype;
-                       currentsd[ncurrent].bus = -1;
-                       currentsd[ncurrent].target = -1;
-                       currentsd[ncurrent].lun = -1;
+                       currentsd[ncurrent] = *this_device;
                        ncurrent++;
                        break;
                  default: 
@@ -1240,6 +1284,7 @@ cciss_update_non_disk_devices(int cntl_num, int hostno)
 out:
        kfree(inq_buff);
        kfree(ld_buff);
+       kfree(currentsd);
        return;
 }
 
index d9c2c586502fbc224d19bc3f4ddc2b075f7e9e02..7b750245ae76b892e4265c6f5ba4af7bbd5731be 100644 (file)
@@ -66,6 +66,10 @@ struct cciss_scsi_dev_t {
        int devtype;
        int bus, target, lun;           /* as presented to the OS */
        unsigned char scsi3addr[8];     /* as presented to the HW */
+       unsigned char device_id[16];    /* from inquiry pg. 0x83 */
+       unsigned char vendor[8];        /* bytes 8-15 of inquiry data */
+       unsigned char model[16];        /* bytes 16-31 of inquiry data */
+       unsigned char revision[4];      /* bytes 32-35 of inquiry data */
 };
 
 struct cciss_scsi_hba_t {
index 09c14341e6e39582c4230d71ec8bddb384e26610..3d967525e9a96f0bfafcb7aa1d95a9e9e42b4fc8 100644 (file)
@@ -424,7 +424,7 @@ static int __init cpqarray_register_ctlr( int i, struct pci_dev *pdev)
                hba[i]->pci_dev, NR_CMDS * sizeof(cmdlist_t),
                &(hba[i]->cmd_pool_dhandle));
        hba[i]->cmd_pool_bits = kcalloc(
-               (NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG, sizeof(unsigned long),
+               DIV_ROUND_UP(NR_CMDS, BITS_PER_LONG), sizeof(unsigned long),
                GFP_KERNEL);
 
        if (!hba[i]->cmd_pool_bits || !hba[i]->cmd_pool)
index 395f8ea7981c54f2fc5b6dfec3cf99acfd83e1ff..cf64ddf5d83924a1c6445a207ee7d21825483436 100644 (file)
@@ -423,8 +423,15 @@ static struct floppy_raw_cmd *raw_cmd, default_raw_cmd;
  * 1581's logical side 0 is on physical side 1, whereas the Sharp's logical
  * side 0 is on physical side 0 (but with the misnamed sector IDs).
  * 'stretch' should probably be renamed to something more general, like
- * 'options'.  Other parameters should be self-explanatory (see also
- * setfdprm(8)).
+ * 'options'.
+ *
+ * Bits 2 through 9 of 'stretch' tell the number of the first sector.
+ * The LSB (bit 2) is flipped. For most disks, the first sector
+ * is 1 (represented by 0x00<<2).  For some CP/M and music sampler
+ * disks (such as Ensoniq EPS 16plus) it is 0 (represented as 0x01<<2).
+ * For Amstrad CPC disks it is 0xC1 (represented as 0xC0<<2).
+ *
+ * Other parameters should be self-explanatory (see also setfdprm(8)).
  */
 /*
            Size
@@ -1355,20 +1362,20 @@ static void fdc_specify(void)
        }
 
        /* Convert step rate from microseconds to milliseconds and 4 bits */
-       srt = 16 - (DP->srt * scale_dtr / 1000 + NOMINAL_DTR - 1) / NOMINAL_DTR;
+       srt = 16 - DIV_ROUND_UP(DP->srt * scale_dtr / 1000, NOMINAL_DTR);
        if (slow_floppy) {
                srt = srt / 4;
        }
        SUPBOUND(srt, 0xf);
        INFBOUND(srt, 0);
 
-       hlt = (DP->hlt * scale_dtr / 2 + NOMINAL_DTR - 1) / NOMINAL_DTR;
+       hlt = DIV_ROUND_UP(DP->hlt * scale_dtr / 2, NOMINAL_DTR);
        if (hlt < 0x01)
                hlt = 0x01;
        else if (hlt > 0x7f)
                hlt = hlt_max_code;
 
-       hut = (DP->hut * scale_dtr / 16 + NOMINAL_DTR - 1) / NOMINAL_DTR;
+       hut = DIV_ROUND_UP(DP->hut * scale_dtr / 16, NOMINAL_DTR);
        if (hut < 0x1)
                hut = 0x1;
        else if (hut > 0xf)
@@ -2236,9 +2243,9 @@ static void setup_format_params(int track)
                        }
                }
        }
-       if (_floppy->stretch & FD_ZEROBASED) {
+       if (_floppy->stretch & FD_SECTBASEMASK) {
                for (count = 0; count < F_SECT_PER_TRACK; count++)
-                       here[count].sect--;
+                       here[count].sect += FD_SECTBASE(_floppy) - 1;
        }
 }
 
@@ -2385,7 +2392,7 @@ static void rw_interrupt(void)
 
 #ifdef FLOPPY_SANITY_CHECK
        if (nr_sectors / ssize >
-           (in_sector_offset + current_count_sectors + ssize - 1) / ssize) {
+           DIV_ROUND_UP(in_sector_offset + current_count_sectors, ssize)) {
                DPRINT("long rw: %x instead of %lx\n",
                       nr_sectors, current_count_sectors);
                printk("rs=%d s=%d\n", R_SECTOR, SECTOR);
@@ -2649,7 +2656,7 @@ static int make_raw_rw_request(void)
        }
        HEAD = fsector_t / _floppy->sect;
 
-       if (((_floppy->stretch & (FD_SWAPSIDES | FD_ZEROBASED)) ||
+       if (((_floppy->stretch & (FD_SWAPSIDES | FD_SECTBASEMASK)) ||
             TESTF(FD_NEED_TWADDLE)) && fsector_t < _floppy->sect)
                max_sector = _floppy->sect;
 
@@ -2679,7 +2686,7 @@ static int make_raw_rw_request(void)
        CODE2SIZE;
        SECT_PER_TRACK = _floppy->sect << 2 >> SIZECODE;
        SECTOR = ((fsector_t % _floppy->sect) << 2 >> SIZECODE) +
-           ((_floppy->stretch & FD_ZEROBASED) ? 0 : 1);
+           FD_SECTBASE(_floppy);
 
        /* tracksize describes the size which can be filled up with sectors
         * of size ssize.
@@ -3311,7 +3318,7 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g,
            g->head <= 0 ||
            g->track <= 0 || g->track > UDP->tracks >> STRETCH(g) ||
            /* check if reserved bits are set */
-           (g->stretch & ~(FD_STRETCH | FD_SWAPSIDES | FD_ZEROBASED)) != 0)
+           (g->stretch & ~(FD_STRETCH | FD_SWAPSIDES | FD_SECTBASEMASK)) != 0)
                return -EINVAL;
        if (type) {
                if (!capable(CAP_SYS_ADMIN))
@@ -3356,7 +3363,7 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g,
                if (DRS->maxblock > user_params[drive].sect ||
                    DRS->maxtrack ||
                    ((user_params[drive].sect ^ oldStretch) &
-                    (FD_SWAPSIDES | FD_ZEROBASED)))
+                    (FD_SWAPSIDES | FD_SECTBASEMASK)))
                        invalidate_drive(bdev);
                else
                        process_fd_request();
index 1778e4a2c672be69ce18e6a8c64e2356ceca5b92..7b3351260d564015c203d9a2342b94d063eaaccb 100644 (file)
@@ -403,7 +403,7 @@ static int nbd_do_it(struct nbd_device *lo)
        BUG_ON(lo->magic != LO_MAGIC);
 
        lo->pid = current->pid;
-       ret = sysfs_create_file(&lo->disk->dev.kobj, &pid_attr.attr);
+       ret = sysfs_create_file(&disk_to_dev(lo->disk)->kobj, &pid_attr.attr);
        if (ret) {
                printk(KERN_ERR "nbd: sysfs_create_file failed!");
                return ret;
@@ -412,7 +412,7 @@ static int nbd_do_it(struct nbd_device *lo)
        while ((req = nbd_read_stat(lo)) != NULL)
                nbd_end_request(req);
 
-       sysfs_remove_file(&lo->disk->dev.kobj, &pid_attr.attr);
+       sysfs_remove_file(&disk_to_dev(lo->disk)->kobj, &pid_attr.attr);
        return 0;
 }
 
index 29b7a648cc6ec639e973a881fb015910fa3992fe..0e077150568bbc78b5f44323019dd8a9bf643f87 100644 (file)
@@ -2544,7 +2544,7 @@ static int pkt_make_request(struct request_queue *q, struct bio *bio)
                if (last_zone != zone) {
                        BUG_ON(last_zone != zone + pd->settings.size);
                        first_sectors = last_zone - bio->bi_sector;
-                       bp = bio_split(bio, bio_split_pool, first_sectors);
+                       bp = bio_split(bio, first_sectors);
                        BUG_ON(!bp);
                        pkt_make_request(q, &bp->bio1);
                        pkt_make_request(q, &bp->bio2);
@@ -2911,7 +2911,7 @@ static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev)
        if (!disk->queue)
                goto out_mem2;
 
-       pd->pkt_dev = MKDEV(disk->major, disk->first_minor);
+       pd->pkt_dev = MKDEV(pktdev_major, idx);
        ret = pkt_new_dev(pd, dev);
        if (ret)
                goto out_new_dev;
index d797e209951d43fe2163e91e32fe392f13296e77..936466f62afd3ad72d4bb4e017f8b9d05a533f5a 100644 (file)
@@ -199,7 +199,8 @@ static void ps3disk_do_request(struct ps3_storage_device *dev,
                if (blk_fs_request(req)) {
                        if (ps3disk_submit_request_sg(dev, req))
                                break;
-               } else if (req->cmd_type == REQ_TYPE_FLUSH) {
+               } else if (req->cmd_type == REQ_TYPE_LINUX_BLOCK &&
+                          req->cmd[0] == REQ_LB_OP_FLUSH) {
                        if (ps3disk_submit_flush_request(dev, req))
                                break;
                } else {
@@ -257,7 +258,8 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data)
                return IRQ_HANDLED;
        }
 
-       if (req->cmd_type == REQ_TYPE_FLUSH) {
+       if (req->cmd_type == REQ_TYPE_LINUX_BLOCK &&
+           req->cmd[0] == REQ_LB_OP_FLUSH) {
                read = 0;
                num_sectors = req->hard_cur_sectors;
                op = "flush";
@@ -405,7 +407,8 @@ static void ps3disk_prepare_flush(struct request_queue *q, struct request *req)
 
        dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__);
 
-       req->cmd_type = REQ_TYPE_FLUSH;
+       req->cmd_type = REQ_TYPE_LINUX_BLOCK;
+       req->cmd[0] = REQ_LB_OP_FLUSH;
 }
 
 static unsigned long ps3disk_mask;
@@ -538,7 +541,7 @@ static int ps3disk_remove(struct ps3_system_bus_device *_dev)
        struct ps3disk_private *priv = dev->sbd.core.driver_data;
 
        mutex_lock(&ps3disk_mask_mutex);
-       __clear_bit(priv->gendisk->first_minor / PS3DISK_MINORS,
+       __clear_bit(MINOR(disk_devt(priv->gendisk)) / PS3DISK_MINORS,
                    &ps3disk_mask);
        mutex_unlock(&ps3disk_mask_mutex);
        del_gendisk(priv->gendisk);
index 42251095134fa7746e8748150089c2dd570d21d8..6ec5fc052786cae3c45cda835afe4ebbb9ca7b82 100644 (file)
@@ -47,20 +47,20 @@ static void blk_done(struct virtqueue *vq)
 
        spin_lock_irqsave(&vblk->lock, flags);
        while ((vbr = vblk->vq->vq_ops->get_buf(vblk->vq, &len)) != NULL) {
-               int uptodate;
+               int error;
                switch (vbr->status) {
                case VIRTIO_BLK_S_OK:
-                       uptodate = 1;
+                       error = 0;
                        break;
                case VIRTIO_BLK_S_UNSUPP:
-                       uptodate = -ENOTTY;
+                       error = -ENOTTY;
                        break;
                default:
-                       uptodate = 0;
+                       error = -EIO;
                        break;
                }
 
-               end_dequeued_request(vbr->req, uptodate);
+               __blk_end_request(vbr->req, error, blk_rq_bytes(vbr->req));
                list_del(&vbr->list);
                mempool_free(vbr, vblk->pool);
        }
@@ -84,11 +84,11 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
        if (blk_fs_request(vbr->req)) {
                vbr->out_hdr.type = 0;
                vbr->out_hdr.sector = vbr->req->sector;
-               vbr->out_hdr.ioprio = vbr->req->ioprio;
+               vbr->out_hdr.ioprio = req_get_ioprio(vbr->req);
        } else if (blk_pc_request(vbr->req)) {
                vbr->out_hdr.type = VIRTIO_BLK_T_SCSI_CMD;
                vbr->out_hdr.sector = 0;
-               vbr->out_hdr.ioprio = vbr->req->ioprio;
+               vbr->out_hdr.ioprio = req_get_ioprio(vbr->req);
        } else {
                /* We don't put anything else in the queue. */
                BUG();
index 3ca643cafccdc6be26bb24532db09ccddeff12f9..bff602ccccf3f66865ea1769fc3b66bbb00162f1 100644 (file)
@@ -105,15 +105,17 @@ static DEFINE_SPINLOCK(blkif_io_lock);
 #define GRANT_INVALID_REF      0
 
 #define PARTS_PER_DISK         16
+#define PARTS_PER_EXT_DISK      256
 
 #define BLKIF_MAJOR(dev) ((dev)>>8)
 #define BLKIF_MINOR(dev) ((dev) & 0xff)
 
-#define DEV_NAME       "xvd"   /* name in /dev */
+#define EXT_SHIFT 28
+#define EXTENDED (1<<EXT_SHIFT)
+#define VDEV_IS_EXTENDED(dev) ((dev)&(EXTENDED))
+#define BLKIF_MINOR_EXT(dev) ((dev)&(~EXTENDED))
 
-/* Information about our VBDs. */
-#define MAX_VBDS 64
-static LIST_HEAD(vbds_list);
+#define DEV_NAME       "xvd"   /* name in /dev */
 
 static int get_id_from_freelist(struct blkfront_info *info)
 {
@@ -386,31 +388,60 @@ static int xlvbd_barrier(struct blkfront_info *info)
 }
 
 
-static int xlvbd_alloc_gendisk(int minor, blkif_sector_t capacity,
-                              int vdevice, u16 vdisk_info, u16 sector_size,
-                              struct blkfront_info *info)
+static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
+                              struct blkfront_info *info,
+                              u16 vdisk_info, u16 sector_size)
 {
        struct gendisk *gd;
        int nr_minors = 1;
        int err = -ENODEV;
+       unsigned int offset;
+       int minor;
+       int nr_parts;
 
        BUG_ON(info->gd != NULL);
        BUG_ON(info->rq != NULL);
 
-       if ((minor % PARTS_PER_DISK) == 0)
-               nr_minors = PARTS_PER_DISK;
+       if ((info->vdevice>>EXT_SHIFT) > 1) {
+               /* this is above the extended range; something is wrong */
+               printk(KERN_WARNING "blkfront: vdevice 0x%x is above the extended range; ignoring\n", info->vdevice);
+               return -ENODEV;
+       }
+
+       if (!VDEV_IS_EXTENDED(info->vdevice)) {
+               minor = BLKIF_MINOR(info->vdevice);
+               nr_parts = PARTS_PER_DISK;
+       } else {
+               minor = BLKIF_MINOR_EXT(info->vdevice);
+               nr_parts = PARTS_PER_EXT_DISK;
+       }
+
+       if ((minor % nr_parts) == 0)
+               nr_minors = nr_parts;
 
        gd = alloc_disk(nr_minors);
        if (gd == NULL)
                goto out;
 
-       if (nr_minors > 1)
-               sprintf(gd->disk_name, "%s%c", DEV_NAME,
-                       'a' + minor / PARTS_PER_DISK);
-       else
-               sprintf(gd->disk_name, "%s%c%d", DEV_NAME,
-                       'a' + minor / PARTS_PER_DISK,
-                       minor % PARTS_PER_DISK);
+       offset = minor / nr_parts;
+
+       if (nr_minors > 1) {
+               if (offset < 26)
+                       sprintf(gd->disk_name, "%s%c", DEV_NAME, 'a' + offset);
+               else
+                       sprintf(gd->disk_name, "%s%c%c", DEV_NAME,
+                               'a' + ((offset / 26)-1), 'a' + (offset % 26));
+       } else {
+               if (offset < 26)
+                       sprintf(gd->disk_name, "%s%c%d", DEV_NAME,
+                               'a' + offset,
+                               minor & (nr_parts - 1));
+               else
+                       sprintf(gd->disk_name, "%s%c%c%d", DEV_NAME,
+                               'a' + ((offset / 26) - 1),
+                               'a' + (offset % 26),
+                               minor & (nr_parts - 1));
+       }
 
        gd->major = XENVBD_MAJOR;
        gd->first_minor = minor;
@@ -699,8 +730,13 @@ static int blkfront_probe(struct xenbus_device *dev,
        err = xenbus_scanf(XBT_NIL, dev->nodename,
                           "virtual-device", "%i", &vdevice);
        if (err != 1) {
-               xenbus_dev_fatal(dev, err, "reading virtual-device");
-               return err;
+               /* go looking in the extended area instead */
+               err = xenbus_scanf(XBT_NIL, dev->nodename, "virtual-device-ext",
+                                  "%i", &vdevice);
+               if (err != 1) {
+                       xenbus_dev_fatal(dev, err, "reading virtual-device");
+                       return err;
+               }
        }
 
        info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -861,9 +897,7 @@ static void blkfront_connect(struct blkfront_info *info)
        if (err)
                info->feature_barrier = 0;
 
-       err = xlvbd_alloc_gendisk(BLKIF_MINOR(info->vdevice),
-                                 sectors, info->vdevice,
-                                 binfo, sector_size, info);
+       err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size);
        if (err) {
                xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s",
                                 info->xbdev->otherend);
index 74031de517e6f342e070f7c8d5e057f7e10c78aa..d47f2f80accdd226118ac10192c8f9bd10fe4b0f 100644 (file)
@@ -2097,7 +2097,7 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf,
 
                len = nr * CD_FRAMESIZE_RAW;
 
-               ret = blk_rq_map_user(q, rq, ubuf, len);
+               ret = blk_rq_map_user(q, rq, NULL, ubuf, len, GFP_KERNEL);
                if (ret)
                        break;
 
index 1231d95aa695b2e070964fa0014fea76af756838..d6ba77a2dd7bbbe6a8329a6485246299226c22fe 100644 (file)
@@ -624,14 +624,14 @@ static void gdrom_readdisk_dma(struct work_struct *work)
                ctrl_outb(1, GDROM_DMA_STATUS_REG);
                wait_event_interruptible_timeout(request_queue,
                        gd.transfer == 0, GDROM_DEFAULT_TIMEOUT);
-               err = gd.transfer;
+               err = gd.transfer ? -EIO : 0;
                gd.transfer = 0;
                gd.pending = 0;
                /* now seek to take the request spinlock
                * before handling ending the request */
                spin_lock(&gdrom_lock);
                list_del_init(&req->queuelist);
-               end_dequeued_request(req, 1 - err);
+               __blk_end_request(req, err, blk_rq_bytes(req));
        }
        spin_unlock(&gdrom_lock);
        kfree(read_command);
index 7ce1ac4baa6d81feccad163cb9c476edfb7278c9..6af435b89867a7bb99689871624989dd8de14e61 100644 (file)
@@ -661,10 +661,10 @@ void add_disk_randomness(struct gendisk *disk)
        if (!disk || !disk->random)
                return;
        /* first major is 1, so we get >= 0x200 here */
-       DEBUG_ENT("disk event %d:%d\n", disk->major, disk->first_minor);
+       DEBUG_ENT("disk event %d:%d\n",
+                 MAJOR(disk_devt(disk)), MINOR(disk_devt(disk)));
 
-       add_timer_randomness(disk->random,
-                            0x100 + MKDEV(disk->major, disk->first_minor));
+       add_timer_randomness(disk->random, 0x100 + disk_devt(disk));
 }
 #endif
 
index 3738cfa209ff2024b77d9790ea91777ab1783c83..f5fc64f89c5c3b71a54a874020e1f8108c9e025e 100644 (file)
@@ -6,6 +6,7 @@ menuconfig TCG_TPM
        tristate "TPM Hardware Support"
        depends on HAS_IOMEM
        depends on EXPERIMENTAL
+       select SECURITYFS
        ---help---
          If you have a TPM security chip in your system, which
          implements the Trusted Computing Group's specification,
index d568c65c137089a1f6402237404c80bb1d402dc1..d9e7a49d6cbf089da4f14f054695bf6be727200e 100644 (file)
@@ -279,7 +279,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
                { "OTES1 Fan",          36, 2, 60, 1, 0 },
                { NULL, 0, 0, 0, 0, 0 } }
        },
-       { 0x0011, NULL /* Abit AT8 32X, need DMI string */, {
+       { 0x0011, "AT8 32X(ATI RD580-ULI M1575)", {
                { "CPU Core",            0, 0, 10, 1, 0 },
                { "DDR",                 1, 0, 20, 1, 0 },
                { "DDR VTT",             2, 0, 10, 1, 0 },
@@ -303,6 +303,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
                { "SYS Fan",            34, 2, 60, 1, 0 },
                { "AUX1 Fan",           35, 2, 60, 1, 0 },
                { "AUX2 Fan",           36, 2, 60, 1, 0 },
+               { "AUX3 Fan",           37, 2, 60, 1, 0 },
                { NULL, 0, 0, 0, 0, 0 } }
        },
        { 0x0012, NULL /* Abit AN8 32X, need DMI string */, {
index f1133081cc42789b642a9e11c76c5efa6749a618..d793cc0119908abd5494ed9f531a27f3dbbb478b 100644 (file)
@@ -46,6 +46,8 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/sysfs.h>
+#include <linux/string.h>
+#include <linux/dmi.h>
 #include <asm/io.h>
 
 #define DRVNAME "it87"
@@ -236,6 +238,8 @@ struct it87_sio_data {
        /* Values read from Super-I/O config space */
        u8 revision;
        u8 vid_value;
+       /* Values set based on DMI strings */
+       u8 skip_pwm;
 };
 
 /* For each registered chip, we need to keep some data in memory.
@@ -964,6 +968,7 @@ static int __init it87_find(unsigned short *address,
 {
        int err = -ENODEV;
        u16 chip_type;
+       const char *board_vendor, *board_name;
 
        superio_enter();
        chip_type = force_id ? force_id : superio_inw(DEVID);
@@ -1022,6 +1027,24 @@ static int __init it87_find(unsigned short *address,
                        pr_info("it87: in7 is VCCH (+5V Stand-By)\n");
        }
 
+       /* Disable specific features based on DMI strings */
+       board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
+       board_name = dmi_get_system_info(DMI_BOARD_NAME);
+       if (board_vendor && board_name) {
+               if (strcmp(board_vendor, "nVIDIA") == 0
+                && strcmp(board_name, "FN68PT") == 0) {
+                       /* On the Shuttle SN68PT, FAN_CTL2 is apparently not
+                          connected to a fan, but to something else. One user
+                          has reported instant system power-off when changing
+                          the PWM2 duty cycle, so we disable it.
+                          I use the board name string as the trigger in case
+                          the same board is ever used in other systems. */
+                       pr_info("it87: Disabling pwm2 due to "
+                               "hardware constraints\n");
+                       sio_data->skip_pwm = (1 << 1);
+               }
+       }
+
 exit:
        superio_exit();
        return err;
@@ -1168,25 +1191,33 @@ static int __devinit it87_probe(struct platform_device *pdev)
        }
 
        if (enable_pwm_interface) {
-               if ((err = device_create_file(dev,
-                    &sensor_dev_attr_pwm1_enable.dev_attr))
-                || (err = device_create_file(dev,
-                    &sensor_dev_attr_pwm2_enable.dev_attr))
-                || (err = device_create_file(dev,
-                    &sensor_dev_attr_pwm3_enable.dev_attr))
-                || (err = device_create_file(dev,
-                    &sensor_dev_attr_pwm1.dev_attr))
-                || (err = device_create_file(dev,
-                    &sensor_dev_attr_pwm2.dev_attr))
-                || (err = device_create_file(dev,
-                    &sensor_dev_attr_pwm3.dev_attr))
-                || (err = device_create_file(dev,
-                    &dev_attr_pwm1_freq))
-                || (err = device_create_file(dev,
-                    &dev_attr_pwm2_freq))
-                || (err = device_create_file(dev,
-                    &dev_attr_pwm3_freq)))
-                       goto ERROR4;
+               if (!(sio_data->skip_pwm & (1 << 0))) {
+                       if ((err = device_create_file(dev,
+                            &sensor_dev_attr_pwm1_enable.dev_attr))
+                        || (err = device_create_file(dev,
+                            &sensor_dev_attr_pwm1.dev_attr))
+                        || (err = device_create_file(dev,
+                            &dev_attr_pwm1_freq)))
+                               goto ERROR4;
+               }
+               if (!(sio_data->skip_pwm & (1 << 1))) {
+                       if ((err = device_create_file(dev,
+                            &sensor_dev_attr_pwm2_enable.dev_attr))
+                        || (err = device_create_file(dev,
+                            &sensor_dev_attr_pwm2.dev_attr))
+                        || (err = device_create_file(dev,
+                            &dev_attr_pwm2_freq)))
+                               goto ERROR4;
+               }
+               if (!(sio_data->skip_pwm & (1 << 2))) {
+                       if ((err = device_create_file(dev,
+                            &sensor_dev_attr_pwm3_enable.dev_attr))
+                        || (err = device_create_file(dev,
+                            &sensor_dev_attr_pwm3.dev_attr))
+                        || (err = device_create_file(dev,
+                            &dev_attr_pwm3_freq)))
+                               goto ERROR4;
+               }
        }
 
        if (data->type == it8712 || data->type == it8716
@@ -1546,6 +1577,7 @@ static int __init sm_it87_init(void)
        unsigned short isa_address=0;
        struct it87_sio_data sio_data;
 
+       memset(&sio_data, 0, sizeof(struct it87_sio_data));
        err = it87_find(&isa_address, &sio_data);
        if (err)
                return err;
index f16bb4667238acb65d0a9f3af3ee1421858194a6..03c2cb6a58bc063070d04d4d63f715e7520e1fd0 100644 (file)
@@ -1113,7 +1113,7 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
 
        if (write) {
                /* disk has become write protected */
-               if (cd->disk->policy) {
+               if (get_disk_ro(cd->disk)) {
                        cdrom_end_request(drive, 0);
                        return ide_stopped;
                }
index 07ef88bd109b69a04c0addfcac588024ea7286dd..33ea8c048717d51a293306211721e7120fe35117 100644 (file)
 #include <asm/io.h>
 #include <asm/div64.h>
 
+#if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT)
+#define IDE_DISK_MINORS                (1 << PARTN_BITS)
+#else
+#define IDE_DISK_MINORS                0
+#endif
+
 struct ide_disk_obj {
        ide_drive_t     *drive;
        ide_driver_t    *driver;
@@ -1151,8 +1157,7 @@ static int ide_disk_probe(ide_drive_t *drive)
        if (!idkp)
                goto failed;
 
-       g = alloc_disk_node(1 << PARTN_BITS,
-                       hwif_to_node(drive->hwif));
+       g = alloc_disk_node(IDE_DISK_MINORS, hwif_to_node(drive->hwif));
        if (!g)
                goto out_free_idkp;
 
@@ -1178,9 +1183,11 @@ static int ide_disk_probe(ide_drive_t *drive)
        } else
                drive->attach = 1;
 
-       g->minors = 1 << PARTN_BITS;
+       g->minors = IDE_DISK_MINORS;
        g->driverfs_dev = &drive->gendev;
-       g->flags = drive->removable ? GENHD_FL_REMOVABLE : 0;
+       g->flags |= GENHD_FL_EXT_DEVT;
+       if (drive->removable)
+               g->flags |= GENHD_FL_REMOVABLE;
        set_capacity(g, idedisk_capacity(drive));
        g->fops = &idedisk_ops;
        add_disk(g);
index a51a30e9eab3c1e1712fc3924fa934113acef10a..70aa86c8807ed292aa3407464c27889fd598a810 100644 (file)
@@ -1188,7 +1188,7 @@ static struct kobject *exact_match(dev_t dev, int *part, void *data)
 {
        struct gendisk *p = data;
        *part &= (1 << PARTN_BITS) - 1;
-       return &p->dev.kobj;
+       return &disk_to_dev(p)->kobj;
 }
 
 static int exact_lock(dev_t dev, void *data)
index 922d35f4fc08aa07d69355a812577f9534e82567..3cab0cedfca21f54d83027a78f1f6c6a3c1a1b8e 100644 (file)
@@ -3748,6 +3748,7 @@ error1:
                cm_remove_port_fs(port);
        }
        device_unregister(cm_dev->device);
+       kfree(cm_dev);
 }
 
 static void cm_remove_one(struct ib_device *ib_device)
@@ -3776,6 +3777,7 @@ static void cm_remove_one(struct ib_device *ib_device)
                cm_remove_port_fs(port);
        }
        device_unregister(cm_dev->device);
+       kfree(cm_dev);
 }
 
 static int __init ib_cm_init(void)
index 1adf2efd3cb392b84800241ccca3fbc4d1ffb4ac..49c45feccd5b4148d2e73afff3c846185b9ed75b 100644 (file)
@@ -1697,9 +1697,8 @@ static inline int rcv_has_same_gid(struct ib_mad_agent_private *mad_agent_priv,
        u8 port_num = mad_agent_priv->agent.port_num;
        u8 lmc;
 
-       send_resp = ((struct ib_mad *)(wr->send_buf.mad))->
-                    mad_hdr.method & IB_MGMT_METHOD_RESP;
-       rcv_resp = rwc->recv_buf.mad->mad_hdr.method & IB_MGMT_METHOD_RESP;
+       send_resp = ib_response_mad((struct ib_mad *)wr->send_buf.mad);
+       rcv_resp = ib_response_mad(rwc->recv_buf.mad);
 
        if (send_resp == rcv_resp)
                /* both requests, or both responses. GIDs different */
index 2acf9b62cf9936acf72f25f2c15bc8bdee41493d..69580e282af012a918fb6bf258333a34f258a584 100644 (file)
@@ -272,7 +272,6 @@ static struct ib_qp *c2_create_qp(struct ib_pd *pd,
                pr_debug("%s: Invalid QP type: %d\n", __func__,
                        init_attr->qp_type);
                return ERR_PTR(-EINVAL);
-               break;
        }
 
        if (err) {
index eb778bfd6f66e306e48133cf806e6544ae529594..ecff98043589c5e15646d28f028e81858d3a6562 100644 (file)
@@ -1155,13 +1155,11 @@ static int iwch_query_port(struct ib_device *ibdev,
                           u8 port, struct ib_port_attr *props)
 {
        PDBG("%s ibdev %p\n", __func__, ibdev);
+
+       memset(props, 0, sizeof(struct ib_port_attr));
        props->max_mtu = IB_MTU_4096;
-       props->lid = 0;
-       props->lmc = 0;
-       props->sm_lid = 0;
-       props->sm_sl = 0;
+       props->active_mtu = IB_MTU_2048;
        props->state = IB_PORT_ACTIVE;
-       props->phys_state = 0;
        props->port_cap_flags =
            IB_PORT_CM_SUP |
            IB_PORT_SNMP_TUNNEL_SUP |
@@ -1170,7 +1168,6 @@ static int iwch_query_port(struct ib_device *ibdev,
            IB_PORT_VENDOR_CLASS_SUP | IB_PORT_BOOT_MGMT_SUP;
        props->gid_tbl_len = 1;
        props->pkey_tbl_len = 1;
-       props->qkey_viol_cntr = 0;
        props->active_width = 2;
        props->active_speed = 2;
        props->max_msg_sz = -1;
index 1ab919f836a8c516c797619e565cc091e5ee04d9..5d7b7855afb9d2c8fe9178e11d9dcf60cc41096d 100644 (file)
@@ -164,6 +164,13 @@ struct ehca_qmap_entry {
        u16 reported;
 };
 
+struct ehca_queue_map {
+       struct ehca_qmap_entry *map;
+       unsigned int entries;
+       unsigned int tail;
+       unsigned int left_to_poll;
+};
+
 struct ehca_qp {
        union {
                struct ib_qp ib_qp;
@@ -173,8 +180,9 @@ struct ehca_qp {
        enum ehca_ext_qp_type ext_type;
        enum ib_qp_state state;
        struct ipz_queue ipz_squeue;
-       struct ehca_qmap_entry *sq_map;
+       struct ehca_queue_map sq_map;
        struct ipz_queue ipz_rqueue;
+       struct ehca_queue_map rq_map;
        struct h_galpas galpas;
        u32 qkey;
        u32 real_qp_num;
@@ -204,6 +212,8 @@ struct ehca_qp {
        atomic_t nr_events; /* events seen */
        wait_queue_head_t wait_completion;
        int mig_armed;
+       struct list_head sq_err_node;
+       struct list_head rq_err_node;
 };
 
 #define IS_SRQ(qp) (qp->ext_type == EQPT_SRQ)
@@ -233,6 +243,8 @@ struct ehca_cq {
        /* mmap counter for resources mapped into user space */
        u32 mm_count_queue;
        u32 mm_count_galpa;
+       struct list_head sqp_err_list;
+       struct list_head rqp_err_list;
 };
 
 enum ehca_mr_flag {
index 5540b276a33cab4877bdf56833f16fc0c316fb22..33647a95eb9a03f1ff5a47c760fb6d3fc5c2d483 100644 (file)
@@ -276,6 +276,9 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
        for (i = 0; i < QP_HASHTAB_LEN; i++)
                INIT_HLIST_HEAD(&my_cq->qp_hashtab[i]);
 
+       INIT_LIST_HEAD(&my_cq->sqp_err_list);
+       INIT_LIST_HEAD(&my_cq->rqp_err_list);
+
        if (context) {
                struct ipz_queue *ipz_queue = &my_cq->ipz_queue;
                struct ehca_create_cq_resp resp;
index a8a2ea585d2f93c038300652e4a329f55ede6f27..8f7f282ead65c01ab05259a5a851968ef05c9eee 100644 (file)
@@ -197,6 +197,8 @@ void ehca_poll_eqs(unsigned long data);
 int ehca_calc_ipd(struct ehca_shca *shca, int port,
                  enum ib_rate path_rate, u32 *ipd);
 
+void ehca_add_to_err_list(struct ehca_qp *qp, int on_sq);
+
 #ifdef CONFIG_PPC_64K_PAGES
 void *ehca_alloc_fw_ctrlblock(gfp_t flags);
 void ehca_free_fw_ctrlblock(void *ptr);
index b6bcee036734ff6ee0ff063196463a9b90cb7c40..4dbe2870e0145fac40e3e31e3d8a01298fa10f17 100644 (file)
@@ -396,6 +396,50 @@ static void ehca_determine_small_queue(struct ehca_alloc_queue_parms *queue,
        queue->is_small = (queue->page_size != 0);
 }
 
+/* needs to be called with cq->spinlock held */
+void ehca_add_to_err_list(struct ehca_qp *qp, int on_sq)
+{
+       struct list_head *list, *node;
+
+       /* TODO: support low latency QPs */
+       if (qp->ext_type == EQPT_LLQP)
+               return;
+
+       if (on_sq) {
+               list = &qp->send_cq->sqp_err_list;
+               node = &qp->sq_err_node;
+       } else {
+               list = &qp->recv_cq->rqp_err_list;
+               node = &qp->rq_err_node;
+       }
+
+       if (list_empty(node))
+               list_add_tail(node, list);
+
+       return;
+}
+
+static void del_from_err_list(struct ehca_cq *cq, struct list_head *node)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&cq->spinlock, flags);
+
+       if (!list_empty(node))
+               list_del_init(node);
+
+       spin_unlock_irqrestore(&cq->spinlock, flags);
+}
+
+static void reset_queue_map(struct ehca_queue_map *qmap)
+{
+       int i;
+
+       qmap->tail = 0;
+       for (i = 0; i < qmap->entries; i++)
+               qmap->map[i].reported = 1;
+}
+
 /*
  * Create an ib_qp struct that is either a QP or an SRQ, depending on
  * the value of the is_srq parameter. If init_attr and srq_init_attr share
@@ -407,12 +451,11 @@ static struct ehca_qp *internal_create_qp(
        struct ib_srq_init_attr *srq_init_attr,
        struct ib_udata *udata, int is_srq)
 {
-       struct ehca_qp *my_qp;
+       struct ehca_qp *my_qp, *my_srq = NULL;
        struct ehca_pd *my_pd = container_of(pd, struct ehca_pd, ib_pd);
        struct ehca_shca *shca = container_of(pd->device, struct ehca_shca,
                                              ib_device);
        struct ib_ucontext *context = NULL;
-       u32 nr_qes;
        u64 h_ret;
        int is_llqp = 0, has_srq = 0;
        int qp_type, max_send_sge, max_recv_sge, ret;
@@ -457,8 +500,7 @@ static struct ehca_qp *internal_create_qp(
 
        /* handle SRQ base QPs */
        if (init_attr->srq) {
-               struct ehca_qp *my_srq =
-                       container_of(init_attr->srq, struct ehca_qp, ib_srq);
+               my_srq = container_of(init_attr->srq, struct ehca_qp, ib_srq);
 
                has_srq = 1;
                parms.ext_type = EQPT_SRQBASE;
@@ -716,15 +758,19 @@ static struct ehca_qp *internal_create_qp(
                                 "and pages ret=%i", ret);
                        goto create_qp_exit2;
                }
-               nr_qes = my_qp->ipz_squeue.queue_length /
+
+               my_qp->sq_map.entries = my_qp->ipz_squeue.queue_length /
                         my_qp->ipz_squeue.qe_size;
-               my_qp->sq_map = vmalloc(nr_qes *
+               my_qp->sq_map.map = vmalloc(my_qp->sq_map.entries *
                                        sizeof(struct ehca_qmap_entry));
-               if (!my_qp->sq_map) {
+               if (!my_qp->sq_map.map) {
                        ehca_err(pd->device, "Couldn't allocate squeue "
                                 "map ret=%i", ret);
                        goto create_qp_exit3;
                }
+               INIT_LIST_HEAD(&my_qp->sq_err_node);
+               /* to avoid the generation of bogus flush CQEs */
+               reset_queue_map(&my_qp->sq_map);
        }
 
        if (HAS_RQ(my_qp)) {
@@ -736,6 +782,25 @@ static struct ehca_qp *internal_create_qp(
                                 "and pages ret=%i", ret);
                        goto create_qp_exit4;
                }
+
+               my_qp->rq_map.entries = my_qp->ipz_rqueue.queue_length /
+                       my_qp->ipz_rqueue.qe_size;
+               my_qp->rq_map.map = vmalloc(my_qp->rq_map.entries *
+                               sizeof(struct ehca_qmap_entry));
+               if (!my_qp->rq_map.map) {
+                       ehca_err(pd->device, "Couldn't allocate squeue "
+                                       "map ret=%i", ret);
+                       goto create_qp_exit5;
+               }
+               INIT_LIST_HEAD(&my_qp->rq_err_node);
+               /* to avoid the generation of bogus flush CQEs */
+               reset_queue_map(&my_qp->rq_map);
+       } else if (init_attr->srq) {
+               /* this is a base QP, use the queue map of the SRQ */
+               my_qp->rq_map = my_srq->rq_map;
+               INIT_LIST_HEAD(&my_qp->rq_err_node);
+
+               my_qp->ipz_rqueue = my_srq->ipz_rqueue;
        }
 
        if (is_srq) {
@@ -799,7 +864,7 @@ static struct ehca_qp *internal_create_qp(
                if (ret) {
                        ehca_err(pd->device,
                                 "Couldn't assign qp to send_cq ret=%i", ret);
-                       goto create_qp_exit6;
+                       goto create_qp_exit7;
                }
        }
 
@@ -825,25 +890,29 @@ static struct ehca_qp *internal_create_qp(
                if (ib_copy_to_udata(udata, &resp, sizeof resp)) {
                        ehca_err(pd->device, "Copy to udata failed");
                        ret = -EINVAL;
-                       goto create_qp_exit7;
+                       goto create_qp_exit8;
                }
        }
 
        return my_qp;
 
-create_qp_exit7:
+create_qp_exit8:
        ehca_cq_unassign_qp(my_qp->send_cq, my_qp->real_qp_num);
 
-create_qp_exit6:
+create_qp_exit7:
        kfree(my_qp->mod_qp_parm);
 
+create_qp_exit6:
+       if (HAS_RQ(my_qp))
+               vfree(my_qp->rq_map.map);
+
 create_qp_exit5:
        if (HAS_RQ(my_qp))
                ipz_queue_dtor(my_pd, &my_qp->ipz_rqueue);
 
 create_qp_exit4:
        if (HAS_SQ(my_qp))
-               vfree(my_qp->sq_map);
+               vfree(my_qp->sq_map.map);
 
 create_qp_exit3:
        if (HAS_SQ(my_qp))
@@ -1035,6 +1104,101 @@ static int prepare_sqe_rts(struct ehca_qp *my_qp, struct ehca_shca *shca,
        return 0;
 }
 
+static int calc_left_cqes(u64 wqe_p, struct ipz_queue *ipz_queue,
+                         struct ehca_queue_map *qmap)
+{
+       void *wqe_v;
+       u64 q_ofs;
+       u32 wqe_idx;
+
+       /* convert real to abs address */
+       wqe_p = wqe_p & (~(1UL << 63));
+
+       wqe_v = abs_to_virt(wqe_p);
+
+       if (ipz_queue_abs_to_offset(ipz_queue, wqe_p, &q_ofs)) {
+               ehca_gen_err("Invalid offset for calculating left cqes "
+                               "wqe_p=%#lx wqe_v=%p\n", wqe_p, wqe_v);
+               return -EFAULT;
+       }
+
+       wqe_idx = q_ofs / ipz_queue->qe_size;
+       if (wqe_idx < qmap->tail)
+               qmap->left_to_poll = (qmap->entries - qmap->tail) + wqe_idx;
+       else
+               qmap->left_to_poll = wqe_idx - qmap->tail;
+
+       return 0;
+}
+
+static int check_for_left_cqes(struct ehca_qp *my_qp, struct ehca_shca *shca)
+{
+       u64 h_ret;
+       void *send_wqe_p, *recv_wqe_p;
+       int ret;
+       unsigned long flags;
+       int qp_num = my_qp->ib_qp.qp_num;
+
+       /* this hcall is not supported on base QPs */
+       if (my_qp->ext_type != EQPT_SRQBASE) {
+               /* get send and receive wqe pointer */
+               h_ret = hipz_h_disable_and_get_wqe(shca->ipz_hca_handle,
+                               my_qp->ipz_qp_handle, &my_qp->pf,
+                               &send_wqe_p, &recv_wqe_p, 4);
+               if (h_ret != H_SUCCESS) {
+                       ehca_err(&shca->ib_device, "disable_and_get_wqe() "
+                                "failed ehca_qp=%p qp_num=%x h_ret=%li",
+                                my_qp, qp_num, h_ret);
+                       return ehca2ib_return_code(h_ret);
+               }
+
+               /*
+                * acquire lock to ensure that nobody is polling the cq which
+                * could mean that the qmap->tail pointer is in an
+                * inconsistent state.
+                */
+               spin_lock_irqsave(&my_qp->send_cq->spinlock, flags);
+               ret = calc_left_cqes((u64)send_wqe_p, &my_qp->ipz_squeue,
+                               &my_qp->sq_map);
+               spin_unlock_irqrestore(&my_qp->send_cq->spinlock, flags);
+               if (ret)
+                       return ret;
+
+
+               spin_lock_irqsave(&my_qp->recv_cq->spinlock, flags);
+               ret = calc_left_cqes((u64)recv_wqe_p, &my_qp->ipz_rqueue,
+                               &my_qp->rq_map);
+               spin_unlock_irqrestore(&my_qp->recv_cq->spinlock, flags);
+               if (ret)
+                       return ret;
+       } else {
+               spin_lock_irqsave(&my_qp->send_cq->spinlock, flags);
+               my_qp->sq_map.left_to_poll = 0;
+               spin_unlock_irqrestore(&my_qp->send_cq->spinlock, flags);
+
+               spin_lock_irqsave(&my_qp->recv_cq->spinlock, flags);
+               my_qp->rq_map.left_to_poll = 0;
+               spin_unlock_irqrestore(&my_qp->recv_cq->spinlock, flags);
+       }
+
+       /* this assures flush cqes being generated only for pending wqes */
+       if ((my_qp->sq_map.left_to_poll == 0) &&
+                               (my_qp->rq_map.left_to_poll == 0)) {
+               spin_lock_irqsave(&my_qp->send_cq->spinlock, flags);
+               ehca_add_to_err_list(my_qp, 1);
+               spin_unlock_irqrestore(&my_qp->send_cq->spinlock, flags);
+
+               if (HAS_RQ(my_qp)) {
+                       spin_lock_irqsave(&my_qp->recv_cq->spinlock, flags);
+                       ehca_add_to_err_list(my_qp, 0);
+                       spin_unlock_irqrestore(&my_qp->recv_cq->spinlock,
+                                       flags);
+               }
+       }
+
+       return 0;
+}
+
 /*
  * internal_modify_qp with circumvention to handle aqp0 properly
  * smi_reset2init indicates if this is an internal reset-to-init-call for
@@ -1539,10 +1703,27 @@ static int internal_modify_qp(struct ib_qp *ibqp,
                        goto modify_qp_exit2;
                }
        }
+       if ((qp_new_state == IB_QPS_ERR) && (qp_cur_state != IB_QPS_ERR)) {
+               ret = check_for_left_cqes(my_qp, shca);
+               if (ret)
+                       goto modify_qp_exit2;
+       }
 
        if (statetrans == IB_QPST_ANY2RESET) {
                ipz_qeit_reset(&my_qp->ipz_rqueue);
                ipz_qeit_reset(&my_qp->ipz_squeue);
+
+               if (qp_cur_state == IB_QPS_ERR) {
+                       del_from_err_list(my_qp->send_cq, &my_qp->sq_err_node);
+
+                       if (HAS_RQ(my_qp))
+                               del_from_err_list(my_qp->recv_cq,
+                                                 &my_qp->rq_err_node);
+               }
+               reset_queue_map(&my_qp->sq_map);
+
+               if (HAS_RQ(my_qp))
+                       reset_queue_map(&my_qp->rq_map);
        }
 
        if (attr_mask & IB_QP_QKEY)
@@ -1958,6 +2139,16 @@ static int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp,
        idr_remove(&ehca_qp_idr, my_qp->token);
        write_unlock_irqrestore(&ehca_qp_idr_lock, flags);
 
+       /*
+        * SRQs will never get into an error list and do not have a recv_cq,
+        * so we need to skip them here.
+        */
+       if (HAS_RQ(my_qp) && !IS_SRQ(my_qp))
+               del_from_err_list(my_qp->recv_cq, &my_qp->rq_err_node);
+
+       if (HAS_SQ(my_qp))
+               del_from_err_list(my_qp->send_cq, &my_qp->sq_err_node);
+
        /* now wait until all pending events have completed */
        wait_event(my_qp->wait_completion, !atomic_read(&my_qp->nr_events));
 
@@ -1983,7 +2174,7 @@ static int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp,
        if (qp_type == IB_QPT_GSI) {
                struct ib_event event;
                ehca_info(dev, "device %s: port %x is inactive.",
-                         shca->ib_device.name, port_num);
+                               shca->ib_device.name, port_num);
                event.device = &shca->ib_device;
                event.event = IB_EVENT_PORT_ERR;
                event.element.port_num = port_num;
@@ -1991,11 +2182,15 @@ static int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp,
                ib_dispatch_event(&event);
        }
 
-       if (HAS_RQ(my_qp))
+       if (HAS_RQ(my_qp)) {
                ipz_queue_dtor(my_pd, &my_qp->ipz_rqueue);
+
+               vfree(my_qp->rq_map.map);
+       }
        if (HAS_SQ(my_qp)) {
                ipz_queue_dtor(my_pd, &my_qp->ipz_squeue);
-               vfree(my_qp->sq_map);
+
+               vfree(my_qp->sq_map.map);
        }
        kmem_cache_free(qp_cache, my_qp);
        atomic_dec(&shca->num_qps);
index 4426d82fe7988c32a2da9b471d2e86a5ead90c68..64928079eafa93bc3a73b13aed73bd6ee57b80bb 100644 (file)
 /* in RC traffic, insert an empty RDMA READ every this many packets */
 #define ACK_CIRC_THRESHOLD 2000000
 
+static u64 replace_wr_id(u64 wr_id, u16 idx)
+{
+       u64 ret;
+
+       ret = wr_id & ~QMAP_IDX_MASK;
+       ret |= idx & QMAP_IDX_MASK;
+
+       return ret;
+}
+
+static u16 get_app_wr_id(u64 wr_id)
+{
+       return wr_id & QMAP_IDX_MASK;
+}
+
 static inline int ehca_write_rwqe(struct ipz_queue *ipz_rqueue,
                                  struct ehca_wqe *wqe_p,
-                                 struct ib_recv_wr *recv_wr)
+                                 struct ib_recv_wr *recv_wr,
+                                 u32 rq_map_idx)
 {
        u8 cnt_ds;
        if (unlikely((recv_wr->num_sge < 0) ||
@@ -69,7 +85,7 @@ static inline int ehca_write_rwqe(struct ipz_queue *ipz_rqueue,
        /* clear wqe header until sglist */
        memset(wqe_p, 0, offsetof(struct ehca_wqe, u.ud_av.sg_list));
 
-       wqe_p->work_request_id = recv_wr->wr_id;
+       wqe_p->work_request_id = replace_wr_id(recv_wr->wr_id, rq_map_idx);
        wqe_p->nr_of_data_seg = recv_wr->num_sge;
 
        for (cnt_ds = 0; cnt_ds < recv_wr->num_sge; cnt_ds++) {
@@ -146,6 +162,7 @@ static inline int ehca_write_swqe(struct ehca_qp *qp,
        u64 dma_length;
        struct ehca_av *my_av;
        u32 remote_qkey = send_wr->wr.ud.remote_qkey;
+       struct ehca_qmap_entry *qmap_entry = &qp->sq_map.map[sq_map_idx];
 
        if (unlikely((send_wr->num_sge < 0) ||
                     (send_wr->num_sge > qp->ipz_squeue.act_nr_of_sg))) {
@@ -158,11 +175,10 @@ static inline int ehca_write_swqe(struct ehca_qp *qp,
        /* clear wqe header until sglist */
        memset(wqe_p, 0, offsetof(struct ehca_wqe, u.ud_av.sg_list));
 
-       wqe_p->work_request_id = send_wr->wr_id & ~QMAP_IDX_MASK;
-       wqe_p->work_request_id |= sq_map_idx & QMAP_IDX_MASK;
+       wqe_p->work_request_id = replace_wr_id(send_wr->wr_id, sq_map_idx);
 
-       qp->sq_map[sq_map_idx].app_wr_id = send_wr->wr_id & QMAP_IDX_MASK;
-       qp->sq_map[sq_map_idx].reported = 0;
+       qmap_entry->app_wr_id = get_app_wr_id(send_wr->wr_id);
+       qmap_entry->reported = 0;
 
        switch (send_wr->opcode) {
        case IB_WR_SEND:
@@ -496,7 +512,9 @@ static int internal_post_recv(struct ehca_qp *my_qp,
        struct ehca_wqe *wqe_p;
        int wqe_cnt = 0;
        int ret = 0;
+       u32 rq_map_idx;
        unsigned long flags;
+       struct ehca_qmap_entry *qmap_entry;
 
        if (unlikely(!HAS_RQ(my_qp))) {
                ehca_err(dev, "QP has no RQ  ehca_qp=%p qp_num=%x ext_type=%d",
@@ -524,8 +542,15 @@ static int internal_post_recv(struct ehca_qp *my_qp,
                        }
                        goto post_recv_exit0;
                }
+               /*
+                * Get the index of the WQE in the recv queue. The same index
+                * is used for writing into the rq_map.
+                */
+               rq_map_idx = start_offset / my_qp->ipz_rqueue.qe_size;
+
                /* write a RECV WQE into the QUEUE */
-               ret = ehca_write_rwqe(&my_qp->ipz_rqueue, wqe_p, cur_recv_wr);
+               ret = ehca_write_rwqe(&my_qp->ipz_rqueue, wqe_p, cur_recv_wr,
+                               rq_map_idx);
                /*
                 * if something failed,
                 * reset the free entry pointer to the start value
@@ -540,6 +565,11 @@ static int internal_post_recv(struct ehca_qp *my_qp,
                        }
                        goto post_recv_exit0;
                }
+
+               qmap_entry = &my_qp->rq_map.map[rq_map_idx];
+               qmap_entry->app_wr_id = get_app_wr_id(cur_recv_wr->wr_id);
+               qmap_entry->reported = 0;
+
                wqe_cnt++;
        } /* eof for cur_recv_wr */
 
@@ -596,10 +626,12 @@ static const u8 ib_wc_opcode[255] = {
 /* internal function to poll one entry of cq */
 static inline int ehca_poll_cq_one(struct ib_cq *cq, struct ib_wc *wc)
 {
-       int ret = 0;
+       int ret = 0, qmap_tail_idx;
        struct ehca_cq *my_cq = container_of(cq, struct ehca_cq, ib_cq);
        struct ehca_cqe *cqe;
        struct ehca_qp *my_qp;
+       struct ehca_qmap_entry *qmap_entry;
+       struct ehca_queue_map *qmap;
        int cqe_count = 0, is_error;
 
 repoll:
@@ -674,27 +706,52 @@ repoll:
                goto repoll;
        wc->qp = &my_qp->ib_qp;
 
-       if (!(cqe->w_completion_flags & WC_SEND_RECEIVE_BIT)) {
-               struct ehca_qmap_entry *qmap_entry;
+       if (is_error) {
                /*
-                * We got a send completion and need to restore the original
-                * wr_id.
+                * set left_to_poll to 0 because in error state, we will not
+                * get any additional CQEs
                 */
-               qmap_entry = &my_qp->sq_map[cqe->work_request_id &
-                                           QMAP_IDX_MASK];
+               ehca_add_to_err_list(my_qp, 1);
+               my_qp->sq_map.left_to_poll = 0;
 
-               if (qmap_entry->reported) {
-                       ehca_warn(cq->device, "Double cqe on qp_num=%#x",
-                                 my_qp->real_qp_num);
-                       /* found a double cqe, discard it and read next one */
-                       goto repoll;
-               }
-               wc->wr_id = cqe->work_request_id & ~QMAP_IDX_MASK;
-               wc->wr_id |= qmap_entry->app_wr_id;
-               qmap_entry->reported = 1;
-       else
+               if (HAS_RQ(my_qp))
+                       ehca_add_to_err_list(my_qp, 0);
+               my_qp->rq_map.left_to_poll = 0;
+       }
+
+       qmap_tail_idx = get_app_wr_id(cqe->work_request_id);
+       if (!(cqe->w_completion_flags & WC_SEND_RECEIVE_BIT))
+               /* We got a send completion. */
+               qmap = &my_qp->sq_map;
+       else
                /* We got a receive completion. */
-               wc->wr_id = cqe->work_request_id;
+               qmap = &my_qp->rq_map;
+
+       qmap_entry = &qmap->map[qmap_tail_idx];
+       if (qmap_entry->reported) {
+               ehca_warn(cq->device, "Double cqe on qp_num=%#x",
+                               my_qp->real_qp_num);
+               /* found a double cqe, discard it and read next one */
+               goto repoll;
+       }
+
+       wc->wr_id = replace_wr_id(cqe->work_request_id, qmap_entry->app_wr_id);
+       qmap_entry->reported = 1;
+
+       /* this is a proper completion, we need to advance the tail pointer */
+       if (++qmap->tail == qmap->entries)
+               qmap->tail = 0;
+
+       /* if left_to_poll is decremented to 0, add the QP to the error list */
+       if (qmap->left_to_poll > 0) {
+               qmap->left_to_poll--;
+               if ((my_qp->sq_map.left_to_poll == 0) &&
+                               (my_qp->rq_map.left_to_poll == 0)) {
+                       ehca_add_to_err_list(my_qp, 1);
+                       if (HAS_RQ(my_qp))
+                               ehca_add_to_err_list(my_qp, 0);
+               }
+       }
 
        /* eval ib_wc_opcode */
        wc->opcode = ib_wc_opcode[cqe->optype]-1;
@@ -733,13 +790,88 @@ poll_cq_one_exit0:
        return ret;
 }
 
+static int generate_flush_cqes(struct ehca_qp *my_qp, struct ib_cq *cq,
+                              struct ib_wc *wc, int num_entries,
+                              struct ipz_queue *ipz_queue, int on_sq)
+{
+       int nr = 0;
+       struct ehca_wqe *wqe;
+       u64 offset;
+       struct ehca_queue_map *qmap;
+       struct ehca_qmap_entry *qmap_entry;
+
+       if (on_sq)
+               qmap = &my_qp->sq_map;
+       else
+               qmap = &my_qp->rq_map;
+
+       qmap_entry = &qmap->map[qmap->tail];
+
+       while ((nr < num_entries) && (qmap_entry->reported == 0)) {
+               /* generate flush CQE */
+               memset(wc, 0, sizeof(*wc));
+
+               offset = qmap->tail * ipz_queue->qe_size;
+               wqe = (struct ehca_wqe *)ipz_qeit_calc(ipz_queue, offset);
+               if (!wqe) {
+                       ehca_err(cq->device, "Invalid wqe offset=%#lx on "
+                                "qp_num=%#x", offset, my_qp->real_qp_num);
+                       return nr;
+               }
+
+               wc->wr_id = replace_wr_id(wqe->work_request_id,
+                                         qmap_entry->app_wr_id);
+
+               if (on_sq) {
+                       switch (wqe->optype) {
+                       case WQE_OPTYPE_SEND:
+                               wc->opcode = IB_WC_SEND;
+                               break;
+                       case WQE_OPTYPE_RDMAWRITE:
+                               wc->opcode = IB_WC_RDMA_WRITE;
+                               break;
+                       case WQE_OPTYPE_RDMAREAD:
+                               wc->opcode = IB_WC_RDMA_READ;
+                               break;
+                       default:
+                               ehca_err(cq->device, "Invalid optype=%x",
+                                               wqe->optype);
+                               return nr;
+                       }
+               } else
+                       wc->opcode = IB_WC_RECV;
+
+               if (wqe->wr_flag & WQE_WRFLAG_IMM_DATA_PRESENT) {
+                       wc->ex.imm_data = wqe->immediate_data;
+                       wc->wc_flags |= IB_WC_WITH_IMM;
+               }
+
+               wc->status = IB_WC_WR_FLUSH_ERR;
+
+               wc->qp = &my_qp->ib_qp;
+
+               /* mark as reported and advance tail pointer */
+               qmap_entry->reported = 1;
+               if (++qmap->tail == qmap->entries)
+                       qmap->tail = 0;
+               qmap_entry = &qmap->map[qmap->tail];
+
+               wc++; nr++;
+       }
+
+       return nr;
+
+}
+
 int ehca_poll_cq(struct ib_cq *cq, int num_entries, struct ib_wc *wc)
 {
        struct ehca_cq *my_cq = container_of(cq, struct ehca_cq, ib_cq);
        int nr;
+       struct ehca_qp *err_qp;
        struct ib_wc *current_wc = wc;
        int ret = 0;
        unsigned long flags;
+       int entries_left = num_entries;
 
        if (num_entries < 1) {
                ehca_err(cq->device, "Invalid num_entries=%d ehca_cq=%p "
@@ -749,15 +881,40 @@ int ehca_poll_cq(struct ib_cq *cq, int num_entries, struct ib_wc *wc)
        }
 
        spin_lock_irqsave(&my_cq->spinlock, flags);
-       for (nr = 0; nr < num_entries; nr++) {
+
+       /* generate flush cqes for send queues */
+       list_for_each_entry(err_qp, &my_cq->sqp_err_list, sq_err_node) {
+               nr = generate_flush_cqes(err_qp, cq, current_wc, entries_left,
+                               &err_qp->ipz_squeue, 1);
+               entries_left -= nr;
+               current_wc += nr;
+
+               if (entries_left == 0)
+                       break;
+       }
+
+       /* generate flush cqes for receive queues */
+       list_for_each_entry(err_qp, &my_cq->rqp_err_list, rq_err_node) {
+               nr = generate_flush_cqes(err_qp, cq, current_wc, entries_left,
+                               &err_qp->ipz_rqueue, 0);
+               entries_left -= nr;
+               current_wc += nr;
+
+               if (entries_left == 0)
+                       break;
+       }
+
+       for (nr = 0; nr < entries_left; nr++) {
                ret = ehca_poll_cq_one(cq, current_wc);
                if (ret)
                        break;
                current_wc++;
        } /* eof for nr */
+       entries_left -= nr;
+
        spin_unlock_irqrestore(&my_cq->spinlock, flags);
        if (ret == -EAGAIN  || !ret)
-               ret = nr;
+               ret = num_entries - entries_left;
 
 poll_cq_exit0:
        return ret;
index 97710522624dfe16218e36b09197177a456dba87..7b93cda1a4bdcf9681c652fa525058078b48f570 100644 (file)
@@ -675,7 +675,8 @@ static void send_rc_ack(struct ipath_qp *qp)
        hdr.lrh[0] = cpu_to_be16(lrh0);
        hdr.lrh[1] = cpu_to_be16(qp->remote_ah_attr.dlid);
        hdr.lrh[2] = cpu_to_be16(hwords + SIZE_OF_CRC);
-       hdr.lrh[3] = cpu_to_be16(dd->ipath_lid);
+       hdr.lrh[3] = cpu_to_be16(dd->ipath_lid |
+                                qp->remote_ah_attr.src_path_bits);
        ohdr->bth[0] = cpu_to_be32(bth0);
        ohdr->bth[1] = cpu_to_be32(qp->remote_qpn);
        ohdr->bth[2] = cpu_to_be32(qp->r_ack_psn & IPATH_PSN_MASK);
index af051f7576638197fb9633879f08e36d78ae3620..fc0f6d9e6030f04f5412975f4d2102c67267cbd7 100644 (file)
@@ -618,7 +618,8 @@ void ipath_make_ruc_header(struct ipath_ibdev *dev, struct ipath_qp *qp,
        qp->s_hdr.lrh[0] = cpu_to_be16(lrh0);
        qp->s_hdr.lrh[1] = cpu_to_be16(qp->remote_ah_attr.dlid);
        qp->s_hdr.lrh[2] = cpu_to_be16(qp->s_hdrwords + nwords + SIZE_OF_CRC);
-       qp->s_hdr.lrh[3] = cpu_to_be16(dev->dd->ipath_lid);
+       qp->s_hdr.lrh[3] = cpu_to_be16(dev->dd->ipath_lid |
+                                      qp->remote_ah_attr.src_path_bits);
        bth0 |= ipath_get_pkey(dev->dd, qp->s_pkey_index);
        bth0 |= extra_bytes << 20;
        ohdr->bth[0] = cpu_to_be32(bth0 | (1 << 22));
index b766e40e9ebf601624e3e33eb072e6a9f9e327b6..eabc4247860b429db0d6603bba4e16c943d0af7c 100644 (file)
@@ -340,9 +340,16 @@ static int ipath_post_one_send(struct ipath_qp *qp, struct ib_send_wr *wr)
        int acc;
        int ret;
        unsigned long flags;
+       struct ipath_devdata *dd = to_idev(qp->ibqp.device)->dd;
 
        spin_lock_irqsave(&qp->s_lock, flags);
 
+       if (qp->ibqp.qp_type != IB_QPT_SMI &&
+           !(dd->ipath_flags & IPATH_LINKACTIVE)) {
+               ret = -ENETDOWN;
+               goto bail;
+       }
+
        /* Check that state is OK to post send. */
        if (unlikely(!(ib_ipath_state_ops[qp->state] & IPATH_POST_SEND_OK)))
                goto bail_inval;
index 9559248f265b80090aeecd8c693059e9e43bdad0..baa01deb2436eb5e453a7784c867a3c7105f97d7 100644 (file)
@@ -1058,6 +1058,9 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
        else
                sqd_event = 0;
 
+       if (!ibqp->uobject && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT)
+               context->rlkey |= (1 << 4);
+
        /*
         * Before passing a kernel QP to the HW, make sure that the
         * ownership bits of the send queue are set and the SQ
index cc440f90000becfd62928c8aee85e07d4ef30653..65ad359fdf164e506ec9a5726ba12c5a5ee882f2 100644 (file)
@@ -149,18 +149,10 @@ void mthca_start_catas_poll(struct mthca_dev *dev)
                ((pci_resource_len(dev->pdev, 0) - 1) &
                 dev->catas_err.addr);
 
-       if (!request_mem_region(addr, dev->catas_err.size * 4,
-                               DRV_NAME)) {
-               mthca_warn(dev, "couldn't request catastrophic error region "
-                          "at 0x%lx/0x%x\n", addr, dev->catas_err.size * 4);
-               return;
-       }
-
        dev->catas_err.map = ioremap(addr, dev->catas_err.size * 4);
        if (!dev->catas_err.map) {
                mthca_warn(dev, "couldn't map catastrophic error region "
                           "at 0x%lx/0x%x\n", addr, dev->catas_err.size * 4);
-               release_mem_region(addr, dev->catas_err.size * 4);
                return;
        }
 
@@ -175,13 +167,8 @@ void mthca_stop_catas_poll(struct mthca_dev *dev)
 {
        del_timer_sync(&dev->catas_err.timer);
 
-       if (dev->catas_err.map) {
+       if (dev->catas_err.map)
                iounmap(dev->catas_err.map);
-               release_mem_region(pci_resource_start(dev->pdev, 0) +
-                                  ((pci_resource_len(dev->pdev, 0) - 1) &
-                                   dev->catas_err.addr),
-                                  dev->catas_err.size * 4);
-       }
 
        spin_lock_irq(&catas_lock);
        list_del(&dev->catas_err.list);
index cc6858f0b65bb1d6b6d168cb2ad8aa73315fb817..28f0e0c40d7dfa87c8668c6b8264e8a17859b240 100644 (file)
@@ -652,27 +652,13 @@ static int mthca_map_reg(struct mthca_dev *dev,
 {
        unsigned long base = pci_resource_start(dev->pdev, 0);
 
-       if (!request_mem_region(base + offset, size, DRV_NAME))
-               return -EBUSY;
-
        *map = ioremap(base + offset, size);
-       if (!*map) {
-               release_mem_region(base + offset, size);
+       if (!*map)
                return -ENOMEM;
-       }
 
        return 0;
 }
 
-static void mthca_unmap_reg(struct mthca_dev *dev, unsigned long offset,
-                           unsigned long size, void __iomem *map)
-{
-       unsigned long base = pci_resource_start(dev->pdev, 0);
-
-       release_mem_region(base + offset, size);
-       iounmap(map);
-}
-
 static int mthca_map_eq_regs(struct mthca_dev *dev)
 {
        if (mthca_is_memfree(dev)) {
@@ -699,9 +685,7 @@ static int mthca_map_eq_regs(struct mthca_dev *dev)
                                        dev->fw.arbel.eq_arm_base) + 4, 4,
                                  &dev->eq_regs.arbel.eq_arm)) {
                        mthca_err(dev, "Couldn't map EQ arm register, aborting.\n");
-                       mthca_unmap_reg(dev, (pci_resource_len(dev->pdev, 0) - 1) &
-                                       dev->fw.arbel.clr_int_base, MTHCA_CLR_INT_SIZE,
-                                       dev->clr_base);
+                       iounmap(dev->clr_base);
                        return -ENOMEM;
                }
 
@@ -710,12 +694,8 @@ static int mthca_map_eq_regs(struct mthca_dev *dev)
                                  MTHCA_EQ_SET_CI_SIZE,
                                  &dev->eq_regs.arbel.eq_set_ci_base)) {
                        mthca_err(dev, "Couldn't map EQ CI register, aborting.\n");
-                       mthca_unmap_reg(dev, ((pci_resource_len(dev->pdev, 0) - 1) &
-                                             dev->fw.arbel.eq_arm_base) + 4, 4,
-                                       dev->eq_regs.arbel.eq_arm);
-                       mthca_unmap_reg(dev, (pci_resource_len(dev->pdev, 0) - 1) &
-                                       dev->fw.arbel.clr_int_base, MTHCA_CLR_INT_SIZE,
-                                       dev->clr_base);
+                       iounmap(dev->eq_regs.arbel.eq_arm);
+                       iounmap(dev->clr_base);
                        return -ENOMEM;
                }
        } else {
@@ -731,8 +711,7 @@ static int mthca_map_eq_regs(struct mthca_dev *dev)
                                  &dev->eq_regs.tavor.ecr_base)) {
                        mthca_err(dev, "Couldn't map ecr register, "
                                  "aborting.\n");
-                       mthca_unmap_reg(dev, MTHCA_CLR_INT_BASE, MTHCA_CLR_INT_SIZE,
-                                       dev->clr_base);
+                       iounmap(dev->clr_base);
                        return -ENOMEM;
                }
        }
@@ -744,22 +723,12 @@ static int mthca_map_eq_regs(struct mthca_dev *dev)
 static void mthca_unmap_eq_regs(struct mthca_dev *dev)
 {
        if (mthca_is_memfree(dev)) {
-               mthca_unmap_reg(dev, (pci_resource_len(dev->pdev, 0) - 1) &
-                               dev->fw.arbel.eq_set_ci_base,
-                               MTHCA_EQ_SET_CI_SIZE,
-                               dev->eq_regs.arbel.eq_set_ci_base);
-               mthca_unmap_reg(dev, ((pci_resource_len(dev->pdev, 0) - 1) &
-                                     dev->fw.arbel.eq_arm_base) + 4, 4,
-                               dev->eq_regs.arbel.eq_arm);
-               mthca_unmap_reg(dev, (pci_resource_len(dev->pdev, 0) - 1) &
-                               dev->fw.arbel.clr_int_base, MTHCA_CLR_INT_SIZE,
-                               dev->clr_base);
+               iounmap(dev->eq_regs.arbel.eq_set_ci_base);
+               iounmap(dev->eq_regs.arbel.eq_arm);
+               iounmap(dev->clr_base);
        } else {
-               mthca_unmap_reg(dev, MTHCA_ECR_BASE,
-                               MTHCA_ECR_SIZE + MTHCA_ECR_CLR_SIZE,
-                               dev->eq_regs.tavor.ecr_base);
-               mthca_unmap_reg(dev, MTHCA_CLR_INT_BASE, MTHCA_CLR_INT_SIZE,
-                               dev->clr_base);
+               iounmap(dev->eq_regs.tavor.ecr_base);
+               iounmap(dev->clr_base);
        }
 }
 
index fb9f91b60f30e401cdb24aad39410db6aae0b0f3..52f60f4eea0070a2f763a2bcb8d3a5373f919963 100644 (file)
@@ -921,58 +921,6 @@ err_uar_table_free:
        return err;
 }
 
-static int mthca_request_regions(struct pci_dev *pdev, int ddr_hidden)
-{
-       int err;
-
-       /*
-        * We can't just use pci_request_regions() because the MSI-X
-        * table is right in the middle of the first BAR.  If we did
-        * pci_request_region and grab all of the first BAR, then
-        * setting up MSI-X would fail, since the PCI core wants to do
-        * request_mem_region on the MSI-X vector table.
-        *
-        * So just request what we need right now, and request any
-        * other regions we need when setting up EQs.
-        */
-       if (!request_mem_region(pci_resource_start(pdev, 0) + MTHCA_HCR_BASE,
-                               MTHCA_HCR_SIZE, DRV_NAME))
-               return -EBUSY;
-
-       err = pci_request_region(pdev, 2, DRV_NAME);
-       if (err)
-               goto err_bar2_failed;
-
-       if (!ddr_hidden) {
-               err = pci_request_region(pdev, 4, DRV_NAME);
-               if (err)
-                       goto err_bar4_failed;
-       }
-
-       return 0;
-
-err_bar4_failed:
-       pci_release_region(pdev, 2);
-
-err_bar2_failed:
-       release_mem_region(pci_resource_start(pdev, 0) + MTHCA_HCR_BASE,
-                          MTHCA_HCR_SIZE);
-
-       return err;
-}
-
-static void mthca_release_regions(struct pci_dev *pdev,
-                                 int ddr_hidden)
-{
-       if (!ddr_hidden)
-               pci_release_region(pdev, 4);
-
-       pci_release_region(pdev, 2);
-
-       release_mem_region(pci_resource_start(pdev, 0) + MTHCA_HCR_BASE,
-                          MTHCA_HCR_SIZE);
-}
-
 static int mthca_enable_msi_x(struct mthca_dev *mdev)
 {
        struct msix_entry entries[3];
@@ -1059,7 +1007,7 @@ static int __mthca_init_one(struct pci_dev *pdev, int hca_type)
        if (!(pci_resource_flags(pdev, 4) & IORESOURCE_MEM))
                ddr_hidden = 1;
 
-       err = mthca_request_regions(pdev, ddr_hidden);
+       err = pci_request_regions(pdev, DRV_NAME);
        if (err) {
                dev_err(&pdev->dev, "Cannot obtain PCI resources, "
                        "aborting.\n");
@@ -1196,7 +1144,7 @@ err_free_dev:
        ib_dealloc_device(&mdev->ib_dev);
 
 err_free_res:
-       mthca_release_regions(pdev, ddr_hidden);
+       pci_release_regions(pdev);
 
 err_disable_pdev:
        pci_disable_device(pdev);
@@ -1240,8 +1188,7 @@ static void __mthca_remove_one(struct pci_dev *pdev)
                        pci_disable_msix(pdev);
 
                ib_dealloc_device(&mdev->ib_dev);
-               mthca_release_regions(pdev, mdev->mthca_flags &
-                                     MTHCA_FLAG_DDR_HIDDEN);
+               pci_release_regions(pdev);
                pci_disable_device(pdev);
                pci_set_drvdata(pdev, NULL);
        }
index b0cab64e5e3db0b45e6837a98a9bcfef6fe8e4c4..a2b04d62b1a46d56efd056ad223ccdbc4e77abad 100644 (file)
@@ -70,27 +70,31 @@ int interrupt_mod_interval = 0;
 
 /* Interoperability */
 int mpa_version = 1;
-module_param(mpa_version, int, 0);
+module_param(mpa_version, int, 0644);
 MODULE_PARM_DESC(mpa_version, "MPA version to be used int MPA Req/Resp (0 or 1)");
 
 /* Interoperability */
 int disable_mpa_crc = 0;
-module_param(disable_mpa_crc, int, 0);
+module_param(disable_mpa_crc, int, 0644);
 MODULE_PARM_DESC(disable_mpa_crc, "Disable checking of MPA CRC");
 
 unsigned int send_first = 0;
-module_param(send_first, int, 0);
+module_param(send_first, int, 0644);
 MODULE_PARM_DESC(send_first, "Send RDMA Message First on Active Connection");
 
 
 unsigned int nes_drv_opt = 0;
-module_param(nes_drv_opt, int, 0);
+module_param(nes_drv_opt, int, 0644);
 MODULE_PARM_DESC(nes_drv_opt, "Driver option parameters");
 
 unsigned int nes_debug_level = 0;
 module_param_named(debug_level, nes_debug_level, uint, 0644);
 MODULE_PARM_DESC(debug_level, "Enable debug output level");
 
+unsigned int wqm_quanta = 0x10000;
+module_param(wqm_quanta, int, 0644);
+MODULE_PARM_DESC(wqm_quanta, "WQM quanta");
+
 LIST_HEAD(nes_adapter_list);
 static LIST_HEAD(nes_dev_list);
 
@@ -557,12 +561,32 @@ static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_i
                goto bail5;
        }
        nesdev->nesadapter->et_rx_coalesce_usecs_irq = interrupt_mod_interval;
+       nesdev->nesadapter->wqm_quanta = wqm_quanta;
 
        /* nesdev->base_doorbell_index =
                        nesdev->nesadapter->pd_config_base[PCI_FUNC(nesdev->pcidev->devfn)]; */
        nesdev->base_doorbell_index = 1;
        nesdev->doorbell_start = nesdev->nesadapter->doorbell_start;
-       nesdev->mac_index = PCI_FUNC(nesdev->pcidev->devfn) % nesdev->nesadapter->port_count;
+       if (nesdev->nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) {
+               switch (PCI_FUNC(nesdev->pcidev->devfn) %
+                       nesdev->nesadapter->port_count) {
+               case 1:
+                       nesdev->mac_index = 2;
+                       break;
+               case 2:
+                       nesdev->mac_index = 1;
+                       break;
+               case 3:
+                       nesdev->mac_index = 3;
+                       break;
+               case 0:
+               default:
+                       nesdev->mac_index = 0;
+               }
+       } else {
+               nesdev->mac_index = PCI_FUNC(nesdev->pcidev->devfn) %
+                                               nesdev->nesadapter->port_count;
+       }
 
        tasklet_init(&nesdev->dpc_tasklet, nes_dpc, (unsigned long)nesdev);
 
@@ -581,7 +605,7 @@ static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_i
        nesdev->int_req = (0x101 << PCI_FUNC(nesdev->pcidev->devfn)) |
                        (1 << (PCI_FUNC(nesdev->pcidev->devfn)+16));
        if (PCI_FUNC(nesdev->pcidev->devfn) < 4) {
-               nesdev->int_req |= (1 << (PCI_FUNC(nesdev->pcidev->devfn)+24));
+               nesdev->int_req |= (1 << (PCI_FUNC(nesdev->mac_index)+24));
        }
 
        /* TODO: This really should be the first driver to load, not function 0 */
@@ -772,14 +796,14 @@ static ssize_t nes_show_adapter(struct device_driver *ddp, char *buf)
 
        list_for_each_entry(nesdev, &nes_dev_list, list) {
                if (i == ee_flsh_adapter) {
-                       devfn      = nesdev->nesadapter->devfn;
-                       bus_number = nesdev->nesadapter->bus_number;
+                       devfn = nesdev->pcidev->devfn;
+                       bus_number = nesdev->pcidev->bus->number;
                        break;
                }
                i++;
        }
 
-       return snprintf(buf, PAGE_SIZE, "%x:%x", bus_number, devfn);
+       return snprintf(buf, PAGE_SIZE, "%x:%x\n", bus_number, devfn);
 }
 
 static ssize_t nes_store_adapter(struct device_driver *ddp,
@@ -1050,6 +1074,55 @@ static ssize_t nes_store_idx_data(struct device_driver *ddp,
        return strnlen(buf, count);
 }
 
+
+/**
+ * nes_show_wqm_quanta
+ */
+static ssize_t nes_show_wqm_quanta(struct device_driver *ddp, char *buf)
+{
+       u32 wqm_quanta_value = 0xdead;
+       u32 i = 0;
+       struct nes_device *nesdev;
+
+       list_for_each_entry(nesdev, &nes_dev_list, list) {
+               if (i == ee_flsh_adapter) {
+                       wqm_quanta_value = nesdev->nesadapter->wqm_quanta;
+                       break;
+               }
+               i++;
+       }
+
+       return  snprintf(buf, PAGE_SIZE, "0x%X\n", wqm_quanta);
+}
+
+
+/**
+ * nes_store_wqm_quanta
+ */
+static ssize_t nes_store_wqm_quanta(struct device_driver *ddp,
+                                       const char *buf, size_t count)
+{
+       unsigned long wqm_quanta_value;
+       u32 wqm_config1;
+       u32 i = 0;
+       struct nes_device *nesdev;
+
+       strict_strtoul(buf, 0, &wqm_quanta_value);
+       list_for_each_entry(nesdev, &nes_dev_list, list) {
+               if (i == ee_flsh_adapter) {
+                       nesdev->nesadapter->wqm_quanta = wqm_quanta_value;
+                       wqm_config1 = nes_read_indexed(nesdev,
+                                               NES_IDX_WQM_CONFIG1);
+                       nes_write_indexed(nesdev, NES_IDX_WQM_CONFIG1,
+                                       ((wqm_quanta_value << 1) |
+                                       (wqm_config1 & 0x00000001)));
+                       break;
+               }
+               i++;
+       }
+       return strnlen(buf, count);
+}
+
 static DRIVER_ATTR(adapter, S_IRUSR | S_IWUSR,
                   nes_show_adapter, nes_store_adapter);
 static DRIVER_ATTR(eeprom_cmd, S_IRUSR | S_IWUSR,
@@ -1068,6 +1141,8 @@ static DRIVER_ATTR(idx_addr, S_IRUSR | S_IWUSR,
                   nes_show_idx_addr, nes_store_idx_addr);
 static DRIVER_ATTR(idx_data, S_IRUSR | S_IWUSR,
                   nes_show_idx_data, nes_store_idx_data);
+static DRIVER_ATTR(wqm_quanta, S_IRUSR | S_IWUSR,
+                  nes_show_wqm_quanta, nes_store_wqm_quanta);
 
 static int nes_create_driver_sysfs(struct pci_driver *drv)
 {
@@ -1081,6 +1156,7 @@ static int nes_create_driver_sysfs(struct pci_driver *drv)
        error |= driver_create_file(&drv->driver, &driver_attr_nonidx_data);
        error |= driver_create_file(&drv->driver, &driver_attr_idx_addr);
        error |= driver_create_file(&drv->driver, &driver_attr_idx_data);
+       error |= driver_create_file(&drv->driver, &driver_attr_wqm_quanta);
        return error;
 }
 
@@ -1095,6 +1171,7 @@ static void nes_remove_driver_sysfs(struct pci_driver *drv)
        driver_remove_file(&drv->driver, &driver_attr_nonidx_data);
        driver_remove_file(&drv->driver, &driver_attr_idx_addr);
        driver_remove_file(&drv->driver, &driver_attr_idx_data);
+       driver_remove_file(&drv->driver, &driver_attr_wqm_quanta);
 }
 
 /**
index 8eb7ae96974d0846fe52f28a04f579ce12edd28b..1595dc7bba9dcd6f58d1ff9134f6002ebf9b31b7 100644 (file)
@@ -169,7 +169,7 @@ extern int disable_mpa_crc;
 extern unsigned int send_first;
 extern unsigned int nes_drv_opt;
 extern unsigned int nes_debug_level;
-
+extern unsigned int wqm_quanta;
 extern struct list_head nes_adapter_list;
 
 extern atomic_t cm_connects;
index 499d3cf83e1f28e2ee263ed3e92e2fdb18d1f59b..2caf9da81ad50d6db5db8bce1c24cb21c2bf46d5 100644 (file)
@@ -52,7 +52,7 @@
 #include <linux/random.h>
 #include <linux/list.h>
 #include <linux/threads.h>
-
+#include <net/arp.h>
 #include <net/neighbour.h>
 #include <net/route.h>
 #include <net/ip_fib.h>
@@ -1019,23 +1019,43 @@ static inline int mini_cm_accelerated(struct nes_cm_core *cm_core,
 
 
 /**
- * nes_addr_send_arp
+ * nes_addr_resolve_neigh
  */
-static void nes_addr_send_arp(u32 dst_ip)
+static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip)
 {
        struct rtable *rt;
        struct flowi fl;
+       struct neighbour *neigh;
+       int rc = -1;
+       DECLARE_MAC_BUF(mac);
 
        memset(&fl, 0, sizeof fl);
        fl.nl_u.ip4_u.daddr = htonl(dst_ip);
        if (ip_route_output_key(&init_net, &rt, &fl)) {
                printk("%s: ip_route_output_key failed for 0x%08X\n",
                                __func__, dst_ip);
-               return;
+               return rc;
+       }
+
+       neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, nesvnic->netdev);
+       if (neigh) {
+               if (neigh->nud_state & NUD_VALID) {
+                       nes_debug(NES_DBG_CM, "Neighbor MAC address for 0x%08X"
+                                 " is %s, Gateway is 0x%08X \n", dst_ip,
+                                 print_mac(mac, neigh->ha), ntohl(rt->rt_gateway));
+                       nes_manage_arp_cache(nesvnic->netdev, neigh->ha,
+                                            dst_ip, NES_ARP_ADD);
+                       rc = nes_arp_table(nesvnic->nesdev, dst_ip, NULL,
+                                          NES_ARP_RESOLVE);
+               }
+               neigh_release(neigh);
        }
 
-       neigh_event_send(rt->u.dst.neighbour, NULL);
+       if ((neigh == NULL) || (!(neigh->nud_state & NUD_VALID)))
+               neigh_event_send(rt->u.dst.neighbour, NULL);
+
        ip_rt_put(rt);
+       return rc;
 }
 
 
@@ -1108,9 +1128,11 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core,
        /* get the mac addr for the remote node */
        arpindex = nes_arp_table(nesdev, cm_node->rem_addr, NULL, NES_ARP_RESOLVE);
        if (arpindex < 0) {
-               kfree(cm_node);
-               nes_addr_send_arp(cm_info->rem_addr);
-               return NULL;
+               arpindex = nes_addr_resolve_neigh(nesvnic, cm_info->rem_addr);
+               if (arpindex < 0) {
+                       kfree(cm_node);
+                       return NULL;
+               }
        }
 
        /* copy the mac addr to node context */
@@ -1826,7 +1848,7 @@ static struct nes_cm_listener *mini_cm_listen(struct nes_cm_core *cm_core,
 /**
  * mini_cm_connect - make a connection node with params
  */
-struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core,
+static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core,
        struct nes_vnic *nesvnic, u16 private_data_len,
        void *private_data, struct nes_cm_info *cm_info)
 {
@@ -2007,7 +2029,6 @@ static int mini_cm_close(struct nes_cm_core *cm_core, struct nes_cm_node *cm_nod
                ret = rem_ref_cm_node(cm_core, cm_node);
                break;
        }
-       cm_node->cm_id = NULL;
        return ret;
 }
 
index 1513d4066f1b965b2dc55a878f7cb28353c3e91f..7c49cc882d75c580c0c31e20b987cf177d04fc9c 100644 (file)
@@ -55,18 +55,19 @@ u32 int_mod_cq_depth_24;
 u32 int_mod_cq_depth_16;
 u32 int_mod_cq_depth_4;
 u32 int_mod_cq_depth_1;
-
+static const u8 nes_max_critical_error_count = 100;
 #include "nes_cm.h"
 
 static void nes_cqp_ce_handler(struct nes_device *nesdev, struct nes_hw_cq *cq);
 static void nes_init_csr_ne020(struct nes_device *nesdev, u8 hw_rev, u8 port_count);
 static int nes_init_serdes(struct nes_device *nesdev, u8 hw_rev, u8 port_count,
-                          u8 OneG_Mode);
+                               struct nes_adapter *nesadapter, u8  OneG_Mode);
 static void nes_nic_napi_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq);
 static void nes_process_aeq(struct nes_device *nesdev, struct nes_hw_aeq *aeq);
 static void nes_process_ceq(struct nes_device *nesdev, struct nes_hw_ceq *ceq);
 static void nes_process_iwarp_aeqe(struct nes_device *nesdev,
                                   struct nes_hw_aeqe *aeqe);
+static void process_critical_error(struct nes_device *nesdev);
 static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number);
 static unsigned int nes_reset_adapter_ne020(struct nes_device *nesdev, u8 *OneG_Mode);
 
@@ -222,11 +223,10 @@ static void nes_nic_tune_timer(struct nes_device *nesdev)
        }
 
        /* boundary checking */
-       if (shared_timer->timer_in_use > NES_NIC_FAST_TIMER_HIGH)
-               shared_timer->timer_in_use = NES_NIC_FAST_TIMER_HIGH;
-       else if (shared_timer->timer_in_use < NES_NIC_FAST_TIMER_LOW) {
-               shared_timer->timer_in_use = NES_NIC_FAST_TIMER_LOW;
-       }
+       if (shared_timer->timer_in_use > shared_timer->threshold_high)
+               shared_timer->timer_in_use = shared_timer->threshold_high;
+       else if (shared_timer->timer_in_use < shared_timer->threshold_low)
+               shared_timer->timer_in_use = shared_timer->threshold_low;
 
        nesdev->currcq_count = 0;
 
@@ -292,9 +292,6 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) {
 
        if ((port_count = nes_reset_adapter_ne020(nesdev, &OneG_Mode)) == 0)
                return NULL;
-       if (nes_init_serdes(nesdev, hw_rev, port_count, OneG_Mode))
-               return NULL;
-       nes_init_csr_ne020(nesdev, hw_rev, port_count);
 
        max_qp = nes_read_indexed(nesdev, NES_IDX_QP_CTX_SIZE);
        nes_debug(NES_DBG_INIT, "QP_CTX_SIZE=%u\n", max_qp);
@@ -353,6 +350,22 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) {
        nes_debug(NES_DBG_INIT, "Allocating new nesadapter @ %p, size = %u (actual size = %u).\n",
                        nesadapter, (u32)sizeof(struct nes_adapter), adapter_size);
 
+       if (nes_read_eeprom_values(nesdev, nesadapter)) {
+               printk(KERN_ERR PFX "Unable to read EEPROM data.\n");
+               kfree(nesadapter);
+               return NULL;
+       }
+
+       if (nes_init_serdes(nesdev, hw_rev, port_count, nesadapter,
+                                                       OneG_Mode)) {
+               kfree(nesadapter);
+               return NULL;
+       }
+       nes_init_csr_ne020(nesdev, hw_rev, port_count);
+
+       memset(nesadapter->pft_mcast_map, 255,
+              sizeof nesadapter->pft_mcast_map);
+
        /* populate the new nesadapter */
        nesadapter->devfn = nesdev->pcidev->devfn;
        nesadapter->bus_number = nesdev->pcidev->bus->number;
@@ -468,20 +481,25 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) {
 
        /* setup port configuration */
        if (nesadapter->port_count == 1) {
-               u32temp = 0x00000000;
+               nesadapter->log_port = 0x00000000;
                if (nes_drv_opt & NES_DRV_OPT_DUAL_LOGICAL_PORT)
                        nes_write_indexed(nesdev, NES_IDX_TX_POOL_SIZE, 0x00000002);
                else
                        nes_write_indexed(nesdev, NES_IDX_TX_POOL_SIZE, 0x00000003);
        } else {
-               if (nesadapter->port_count == 2)
-                       u32temp = 0x00000044;
-               else
-                       u32temp = 0x000000e4;
+               if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) {
+                       nesadapter->log_port = 0x000000D8;
+               } else {
+                       if (nesadapter->port_count == 2)
+                               nesadapter->log_port = 0x00000044;
+                       else
+                               nesadapter->log_port = 0x000000e4;
+               }
                nes_write_indexed(nesdev, NES_IDX_TX_POOL_SIZE, 0x00000003);
        }
 
-       nes_write_indexed(nesdev, NES_IDX_NIC_LOGPORT_TO_PHYPORT, u32temp);
+       nes_write_indexed(nesdev, NES_IDX_NIC_LOGPORT_TO_PHYPORT,
+                                               nesadapter->log_port);
        nes_debug(NES_DBG_INIT, "Probe time, LOG2PHY=%u\n",
                        nes_read_indexed(nesdev, NES_IDX_NIC_LOGPORT_TO_PHYPORT));
 
@@ -706,23 +724,43 @@ static unsigned int nes_reset_adapter_ne020(struct nes_device *nesdev, u8 *OneG_
  * nes_init_serdes
  */
 static int nes_init_serdes(struct nes_device *nesdev, u8 hw_rev, u8 port_count,
-                          u8 OneG_Mode)
+                               struct nes_adapter *nesadapter, u8  OneG_Mode)
 {
        int i;
        u32 u32temp;
+       u32 serdes_common_control;
 
        if (hw_rev != NE020_REV) {
                /* init serdes 0 */
 
                nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF);
-               if (!OneG_Mode)
+               if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) {
+                       serdes_common_control = nes_read_indexed(nesdev,
+                                       NES_IDX_ETH_SERDES_COMMON_CONTROL0);
+                       serdes_common_control |= 0x000000100;
+                       nes_write_indexed(nesdev,
+                                       NES_IDX_ETH_SERDES_COMMON_CONTROL0,
+                                       serdes_common_control);
+               } else if (!OneG_Mode) {
                        nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE0, 0x11110000);
-               if (port_count > 1) {
+               }
+               if (((port_count > 1) &&
+                       (nesadapter->phy_type[0] != NES_PHY_TYPE_PUMA_1G)) ||
+                       ((port_count > 2) &&
+                       (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G))) {
                        /* init serdes 1 */
                        nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000000FF);
-                       if (!OneG_Mode)
+                       if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) {
+                               serdes_common_control = nes_read_indexed(nesdev,
+                                       NES_IDX_ETH_SERDES_COMMON_CONTROL1);
+                               serdes_common_control |= 0x000000100;
+                               nes_write_indexed(nesdev,
+                                       NES_IDX_ETH_SERDES_COMMON_CONTROL1,
+                                       serdes_common_control);
+                       } else if (!OneG_Mode) {
                                nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE1, 0x11110000);
                        }
+               }
        } else {
                /* init serdes 0 */
                nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, 0x00000008);
@@ -826,7 +864,8 @@ static void nes_init_csr_ne020(struct nes_device *nesdev, u8 hw_rev, u8 port_cou
 
        nes_write_indexed(nesdev, 0x00005000, 0x00018000);
        /* nes_write_indexed(nesdev, 0x00005000, 0x00010000); */
-       nes_write_indexed(nesdev, 0x00005004, 0x00020001);
+       nes_write_indexed(nesdev, NES_IDX_WQM_CONFIG1, (wqm_quanta << 1) |
+                                                        0x00000001);
        nes_write_indexed(nesdev, 0x00005008, 0x1F1F1F1F);
        nes_write_indexed(nesdev, 0x00005010, 0x1F1F1F1F);
        nes_write_indexed(nesdev, 0x00005018, 0x1F1F1F1F);
@@ -1226,6 +1265,7 @@ int nes_init_phy(struct nes_device *nesdev)
                if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_1G) {
                        printk(PFX "%s: Programming mdc config for 1G\n", __func__);
                        tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG);
+                       tx_config &= 0xFFFFFFE3;
                        tx_config |= 0x04;
                        nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config);
                }
@@ -1291,7 +1331,8 @@ int nes_init_phy(struct nes_device *nesdev)
                    (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_ARGUS)) {
                        /* setup 10G MDIO operation */
                        tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG);
-                       tx_config |= 0x14;
+                       tx_config &= 0xFFFFFFE3;
+                       tx_config |= 0x15;
                        nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config);
                }
                if ((nesadapter->phy_type[mac_index] == NES_PHY_TYPE_ARGUS)) {
@@ -1315,7 +1356,7 @@ int nes_init_phy(struct nes_device *nesdev)
                                nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc319, 0x0008);
                                nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc31a, 0x0098);
                                nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0026, 0x0E00);
-                               nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0027, 0x0000);
+                               nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0027, 0x0001);
                                nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0028, 0xA528);
 
                                /*
@@ -1759,9 +1800,14 @@ int nes_init_nic_qp(struct nes_device *nesdev, struct net_device *netdev)
  */
 void nes_destroy_nic_qp(struct nes_vnic *nesvnic)
 {
+       u64 u64temp;
+       dma_addr_t bus_address;
        struct nes_device *nesdev = nesvnic->nesdev;
        struct nes_hw_cqp_wqe *cqp_wqe;
+       struct nes_hw_nic_sq_wqe *nic_sqe;
        struct nes_hw_nic_rq_wqe *nic_rqe;
+       __le16 *wqe_fragment_length;
+       u16  wqe_fragment_index;
        u64 wqe_frag;
        u32 cqp_head;
        unsigned long flags;
@@ -1770,14 +1816,69 @@ void nes_destroy_nic_qp(struct nes_vnic *nesvnic)
        /* Free remaining NIC receive buffers */
        while (nesvnic->nic.rq_head != nesvnic->nic.rq_tail) {
                nic_rqe   = &nesvnic->nic.rq_vbase[nesvnic->nic.rq_tail];
-               wqe_frag  = (u64)le32_to_cpu(nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX]);
-               wqe_frag |= ((u64)le32_to_cpu(nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX])) << 32;
+               wqe_frag  = (u64)le32_to_cpu(
+                       nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX]);
+               wqe_frag |= ((u64)le32_to_cpu(
+                       nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX]))<<32;
                pci_unmap_single(nesdev->pcidev, (dma_addr_t)wqe_frag,
                                nesvnic->max_frame_size, PCI_DMA_FROMDEVICE);
                dev_kfree_skb(nesvnic->nic.rx_skb[nesvnic->nic.rq_tail++]);
                nesvnic->nic.rq_tail &= (nesvnic->nic.rq_size - 1);
        }
 
+       /* Free remaining NIC transmit buffers */
+       while (nesvnic->nic.sq_head != nesvnic->nic.sq_tail) {
+               nic_sqe = &nesvnic->nic.sq_vbase[nesvnic->nic.sq_tail];
+               wqe_fragment_index = 1;
+               wqe_fragment_length = (__le16 *)
+                       &nic_sqe->wqe_words[NES_NIC_SQ_WQE_LENGTH_0_TAG_IDX];
+               /* bump past the vlan tag */
+               wqe_fragment_length++;
+               if (le16_to_cpu(wqe_fragment_length[wqe_fragment_index]) != 0) {
+                       u64temp = (u64)le32_to_cpu(
+                               nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX+
+                               wqe_fragment_index*2]);
+                       u64temp += ((u64)le32_to_cpu(
+                               nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_HIGH_IDX
+                               + wqe_fragment_index*2]))<<32;
+                       bus_address = (dma_addr_t)u64temp;
+                       if (test_and_clear_bit(nesvnic->nic.sq_tail,
+                                       nesvnic->nic.first_frag_overflow)) {
+                               pci_unmap_single(nesdev->pcidev,
+                                               bus_address,
+                                               le16_to_cpu(wqe_fragment_length[
+                                                       wqe_fragment_index++]),
+                                               PCI_DMA_TODEVICE);
+                       }
+                       for (; wqe_fragment_index < 5; wqe_fragment_index++) {
+                               if (wqe_fragment_length[wqe_fragment_index]) {
+                                       u64temp = le32_to_cpu(
+                                               nic_sqe->wqe_words[
+                                               NES_NIC_SQ_WQE_FRAG0_LOW_IDX+
+                                               wqe_fragment_index*2]);
+                                       u64temp += ((u64)le32_to_cpu(
+                                               nic_sqe->wqe_words[
+                                               NES_NIC_SQ_WQE_FRAG0_HIGH_IDX+
+                                               wqe_fragment_index*2]))<<32;
+                                       bus_address = (dma_addr_t)u64temp;
+                                       pci_unmap_page(nesdev->pcidev,
+                                                       bus_address,
+                                                       le16_to_cpu(
+                                                       wqe_fragment_length[
+                                                       wqe_fragment_index]),
+                                                       PCI_DMA_TODEVICE);
+                               } else
+                                       break;
+                       }
+               }
+               if (nesvnic->nic.tx_skb[nesvnic->nic.sq_tail])
+                       dev_kfree_skb(
+                               nesvnic->nic.tx_skb[nesvnic->nic.sq_tail]);
+
+               nesvnic->nic.sq_tail = (++nesvnic->nic.sq_tail)
+                                       & (nesvnic->nic.sq_size - 1);
+       }
+
        spin_lock_irqsave(&nesdev->cqp.lock, flags);
 
        /* Destroy NIC QP */
@@ -1894,7 +1995,30 @@ int nes_napi_isr(struct nes_device *nesdev)
        }
 }
 
-
+static void process_critical_error(struct nes_device *nesdev)
+{
+       u32 debug_error;
+       u32 nes_idx_debug_error_masks0 = 0;
+       u16 error_module = 0;
+
+       debug_error = nes_read_indexed(nesdev, NES_IDX_DEBUG_ERROR_CONTROL_STATUS);
+       printk(KERN_ERR PFX "Critical Error reported by device!!! 0x%02X\n",
+                       (u16)debug_error);
+       nes_write_indexed(nesdev, NES_IDX_DEBUG_ERROR_CONTROL_STATUS,
+                       0x01010000 | (debug_error & 0x0000ffff));
+       if (crit_err_count++ > 10)
+               nes_write_indexed(nesdev, NES_IDX_DEBUG_ERROR_MASKS1, 1 << 0x17);
+       error_module = (u16) (debug_error & 0x1F00) >> 8;
+       if (++nesdev->nesadapter->crit_error_count[error_module-1] >=
+                       nes_max_critical_error_count) {
+               printk(KERN_ERR PFX "Masking off critical error for module "
+                       "0x%02X\n", (u16)error_module);
+               nes_idx_debug_error_masks0 = nes_read_indexed(nesdev,
+                       NES_IDX_DEBUG_ERROR_MASKS0);
+               nes_write_indexed(nesdev, NES_IDX_DEBUG_ERROR_MASKS0,
+                       nes_idx_debug_error_masks0 | (1 << error_module));
+       }
+}
 /**
  * nes_dpc
  */
@@ -1909,7 +2033,6 @@ void nes_dpc(unsigned long param)
        u32 timer_stat;
        u32 temp_int_stat;
        u32 intf_int_stat;
-       u32 debug_error;
        u32 processed_intf_int = 0;
        u16 processed_timer_int = 0;
        u16 completion_ints = 0;
@@ -1987,14 +2110,7 @@ void nes_dpc(unsigned long param)
                                intf_int_stat = nes_read32(nesdev->regs+NES_INTF_INT_STAT);
                                intf_int_stat &= nesdev->intf_int_req;
                                if (NES_INTF_INT_CRITERR & intf_int_stat) {
-                                       debug_error = nes_read_indexed(nesdev, NES_IDX_DEBUG_ERROR_CONTROL_STATUS);
-                                       printk(KERN_ERR PFX "Critical Error reported by device!!! 0x%02X\n",
-                                                       (u16)debug_error);
-                                       nes_write_indexed(nesdev, NES_IDX_DEBUG_ERROR_CONTROL_STATUS,
-                                                       0x01010000 | (debug_error & 0x0000ffff));
-                                       /* BUG(); */
-                                       if (crit_err_count++ > 10)
-                                               nes_write_indexed(nesdev, NES_IDX_DEBUG_ERROR_MASKS1, 1 << 0x17);
+                                       process_critical_error(nesdev);
                                }
                                if (NES_INTF_INT_PCIERR & intf_int_stat) {
                                        printk(KERN_ERR PFX "PCI Error reported by device!!!\n");
@@ -2258,7 +2374,8 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
                        spin_unlock_irqrestore(&nesadapter->phy_lock, flags);
                }
                /* read the PHY interrupt status register */
-               if (nesadapter->OneG_Mode) {
+               if ((nesadapter->OneG_Mode) &&
+               (nesadapter->phy_type[mac_index] != NES_PHY_TYPE_PUMA_1G)) {
                        do {
                                nes_read_1G_phy_reg(nesdev, 0x1a,
                                                nesadapter->phy_index[mac_index], &phy_data);
@@ -3077,6 +3194,22 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev,
                        nes_cm_disconn(nesqp);
                        break;
                        /* TODO: additional AEs need to be here */
+               case NES_AEQE_AEID_AMP_BOUNDS_VIOLATION:
+                       nesqp = *((struct nes_qp **)&context);
+                       spin_lock_irqsave(&nesqp->lock, flags);
+                       nesqp->hw_iwarp_state = iwarp_state;
+                       nesqp->hw_tcp_state = tcp_state;
+                       nesqp->last_aeq = async_event_id;
+                       spin_unlock_irqrestore(&nesqp->lock, flags);
+                       if (nesqp->ibqp.event_handler) {
+                               ibevent.device = nesqp->ibqp.device;
+                               ibevent.element.qp = &nesqp->ibqp;
+                               ibevent.event = IB_EVENT_QP_ACCESS_ERR;
+                               nesqp->ibqp.event_handler(&ibevent,
+                                               nesqp->ibqp.qp_context);
+                       }
+                       nes_cm_disconn(nesqp);
+                       break;
                default:
                        nes_debug(NES_DBG_AEQ, "Processing an iWARP related AE for QP, misc = 0x%04X\n",
                                        async_event_id);
index 7b81e0ae00760eedf15e58ce12deffbb9daf7490..610b9d859597d2a1ecc9dca6ed54192025b6565c 100644 (file)
@@ -156,6 +156,7 @@ enum indexed_regs {
        NES_IDX_ENDNODE0_NSTAT_TX_OCTETS_HI = 0x7004,
        NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_LO = 0x7008,
        NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_HI = 0x700c,
+       NES_IDX_WQM_CONFIG1 = 0x5004,
        NES_IDX_CM_CONFIG = 0x5100,
        NES_IDX_NIC_LOGPORT_TO_PHYPORT = 0x6000,
        NES_IDX_NIC_PHYPORT_TO_USW = 0x6008,
@@ -967,6 +968,7 @@ struct nes_arp_entry {
 #define DEFAULT_JUMBO_NES_QL_TARGET 40
 #define DEFAULT_JUMBO_NES_QL_HIGH   128
 #define NES_NIC_CQ_DOWNWARD_TREND   16
+#define NES_PFT_SIZE               48
 
 struct nes_hw_tune_timer {
     /* u16 cq_count; */
@@ -1079,6 +1081,7 @@ struct nes_adapter {
        u32 et_rx_max_coalesced_frames_high;
        u32 et_rate_sample_interval;
        u32 timer_int_limit;
+       u32 wqm_quanta;
 
        /* Adapter base MAC address */
        u32 mac_addr_low;
@@ -1094,12 +1097,14 @@ struct nes_adapter {
        u16 pd_config_base[4];
 
        u16 link_interrupt_count[4];
+       u8 crit_error_count[32];
 
        /* the phy index for each port */
        u8  phy_index[4];
        u8  mac_sw_state[4];
        u8  mac_link_down[4];
        u8  phy_type[4];
+       u8  log_port;
 
        /* PCI information */
        unsigned int  devfn;
@@ -1113,6 +1118,7 @@ struct nes_adapter {
        u8            virtwq;
        u8            et_use_adaptive_rx_coalesce;
        u8            adapter_fcn_count;
+       u8 pft_mcast_map[NES_PFT_SIZE];
 };
 
 struct nes_pbl {
index 1b0938c87774e54017dd22364520778547b40dee..730358637bb62603111e936f02ac1ad5c336e780 100644 (file)
@@ -91,6 +91,7 @@ static struct nic_qp_map *nic_qp_mapping_per_function[] = {
 static const u32 default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK
                | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN;
 static int debug = -1;
+static int nics_per_function = 1;
 
 /**
  * nes_netdev_poll
@@ -201,7 +202,8 @@ static int nes_netdev_open(struct net_device *netdev)
                nes_debug(NES_DBG_NETDEV, "i=%d, perfect filter table index= %d, PERF FILTER LOW"
                                " (Addr:%08X) = %08X, HIGH = %08X.\n",
                                i, nesvnic->qp_nic_index[i],
-                               NES_IDX_PERFECT_FILTER_LOW+((nesvnic->perfect_filter_index + i) * 8),
+                               NES_IDX_PERFECT_FILTER_LOW+
+                                       (nesvnic->qp_nic_index[i] * 8),
                                macaddr_low,
                                (u32)macaddr_high | NES_MAC_ADDR_VALID |
                                ((((u32)nesvnic->nic_index) << 16)));
@@ -272,14 +274,18 @@ static int nes_netdev_stop(struct net_device *netdev)
                        break;
        }
 
-       if (first_nesvnic->netdev_open == 0)
+       if ((first_nesvnic->netdev_open == 1) && (first_nesvnic != nesvnic)  &&
+               (PCI_FUNC(first_nesvnic->nesdev->pcidev->devfn) !=
+               PCI_FUNC(nesvnic->nesdev->pcidev->devfn))) {
+                       nes_write_indexed(nesdev, NES_IDX_MAC_INT_MASK+
+                               (0x200*nesdev->mac_index), 0xffffffff);
+                       nes_write_indexed(first_nesvnic->nesdev,
+                               NES_IDX_MAC_INT_MASK+
+                               (0x200*first_nesvnic->nesdev->mac_index),
+                       ~(NES_MAC_INT_LINK_STAT_CHG | NES_MAC_INT_XGMII_EXT |
+                       NES_MAC_INT_TX_UNDERFLOW | NES_MAC_INT_TX_ERROR));
+       } else {
                nes_write_indexed(nesdev, NES_IDX_MAC_INT_MASK+(0x200*nesdev->mac_index), 0xffffffff);
-       else if ((first_nesvnic != nesvnic) &&
-                (PCI_FUNC(first_nesvnic->nesdev->pcidev->devfn) != PCI_FUNC(nesvnic->nesdev->pcidev->devfn))) {
-               nes_write_indexed(nesdev, NES_IDX_MAC_INT_MASK + (0x200 * nesdev->mac_index), 0xffffffff);
-               nes_write_indexed(first_nesvnic->nesdev, NES_IDX_MAC_INT_MASK + (0x200 * first_nesvnic->nesdev->mac_index),
-                               ~(NES_MAC_INT_LINK_STAT_CHG | NES_MAC_INT_XGMII_EXT |
-                               NES_MAC_INT_TX_UNDERFLOW | NES_MAC_INT_TX_ERROR));
        }
 
        nic_active_mask = ~((u32)(1 << nesvnic->nic_index));
@@ -437,7 +443,7 @@ static int nes_netdev_start_xmit(struct sk_buff *skb, struct net_device *netdev)
        struct nes_hw_nic_sq_wqe *nic_sqe;
        struct tcphdr *tcph;
        /* struct udphdr *udph; */
-#define NES_MAX_TSO_FRAGS 18
+#define NES_MAX_TSO_FRAGS MAX_SKB_FRAGS
        /* 64K segment plus overflow on each side */
        dma_addr_t tso_bus_address[NES_MAX_TSO_FRAGS];
        dma_addr_t bus_address;
@@ -605,6 +611,8 @@ tso_sq_no_longer_full:
                                        wqe_fragment_length[wqe_fragment_index] = 0;
                                        set_wqe_64bit_value(nic_sqe->wqe_words, NES_NIC_SQ_WQE_FRAG1_LOW_IDX,
                                                                        bus_address);
+                                       tso_wqe_length += skb_headlen(skb) -
+                                                       original_first_length;
                                }
                                while (wqe_fragment_index < 5) {
                                        wqe_fragment_length[wqe_fragment_index] =
@@ -827,6 +835,7 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev)
 {
        struct nes_vnic *nesvnic = netdev_priv(netdev);
        struct nes_device *nesdev = nesvnic->nesdev;
+       struct nes_adapter *nesadapter = nesvnic->nesdev->nesadapter;
        struct dev_mc_list *multicast_addr;
        u32 nic_active_bit;
        u32 nic_active;
@@ -836,7 +845,12 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev)
        u8 mc_all_on = 0;
        u8 mc_index;
        int mc_nic_index = -1;
+       u8 pft_entries_preallocated = max(nesadapter->adapter_fcn_count *
+                                       nics_per_function, 4);
+       u8 max_pft_entries_avaiable = NES_PFT_SIZE - pft_entries_preallocated;
+       unsigned long flags;
 
+       spin_lock_irqsave(&nesadapter->resource_lock, flags);
        nic_active_bit = 1 << nesvnic->nic_index;
 
        if (netdev->flags & IFF_PROMISC) {
@@ -847,7 +861,7 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev)
                nic_active |= nic_active_bit;
                nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active);
                mc_all_on = 1;
-       } else if ((netdev->flags & IFF_ALLMULTI) || (netdev->mc_count > NES_MULTICAST_PF_MAX) ||
+       } else if ((netdev->flags & IFF_ALLMULTI) ||
                           (nesvnic->nic_index > 3)) {
                nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL);
                nic_active |= nic_active_bit;
@@ -866,17 +880,34 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev)
        }
 
        nes_debug(NES_DBG_NIC_RX, "Number of MC entries = %d, Promiscous = %d, All Multicast = %d.\n",
-                         netdev->mc_count, (netdev->flags & IFF_PROMISC)?1:0,
-                         (netdev->flags & IFF_ALLMULTI)?1:0);
+                 netdev->mc_count, !!(netdev->flags & IFF_PROMISC),
+                 !!(netdev->flags & IFF_ALLMULTI));
        if (!mc_all_on) {
                multicast_addr = netdev->mc_list;
-               perfect_filter_register_address = NES_IDX_PERFECT_FILTER_LOW + 0x80;
-               perfect_filter_register_address += nesvnic->nic_index*0x40;
-               for (mc_index=0; mc_index < NES_MULTICAST_PF_MAX; mc_index++) {
-                       while (multicast_addr && nesvnic->mcrq_mcast_filter && ((mc_nic_index = nesvnic->mcrq_mcast_filter(nesvnic, multicast_addr->dmi_addr)) == 0))
+               perfect_filter_register_address = NES_IDX_PERFECT_FILTER_LOW +
+                                               pft_entries_preallocated * 0x8;
+               for (mc_index = 0; mc_index < max_pft_entries_avaiable;
+               mc_index++) {
+                       while (multicast_addr && nesvnic->mcrq_mcast_filter &&
+                       ((mc_nic_index = nesvnic->mcrq_mcast_filter(nesvnic,
+                                       multicast_addr->dmi_addr)) == 0)) {
                                multicast_addr = multicast_addr->next;
+                       }
                        if (mc_nic_index < 0)
                                mc_nic_index = nesvnic->nic_index;
+                       while (nesadapter->pft_mcast_map[mc_index] < 16 &&
+                               nesadapter->pft_mcast_map[mc_index] !=
+                                       nesvnic->nic_index &&
+                                       mc_index < max_pft_entries_avaiable) {
+                                               nes_debug(NES_DBG_NIC_RX,
+                                       "mc_index=%d skipping nic_index=%d,\
+                                       used for=%d \n", mc_index,
+                                       nesvnic->nic_index,
+                                       nesadapter->pft_mcast_map[mc_index]);
+                               mc_index++;
+                       }
+                       if (mc_index >= max_pft_entries_avaiable)
+                               break;
                        if (multicast_addr) {
                                DECLARE_MAC_BUF(mac);
                                nes_debug(NES_DBG_NIC_RX, "Assigning MC Address %s to register 0x%04X nic_idx=%d\n",
@@ -897,15 +928,33 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev)
                                                (u32)macaddr_high | NES_MAC_ADDR_VALID |
                                                ((((u32)(1<<mc_nic_index)) << 16)));
                                multicast_addr = multicast_addr->next;
+                               nesadapter->pft_mcast_map[mc_index] =
+                                                       nesvnic->nic_index;
                        } else {
                                nes_debug(NES_DBG_NIC_RX, "Clearing MC Address at register 0x%04X\n",
                                                  perfect_filter_register_address+(mc_index * 8));
                                nes_write_indexed(nesdev,
                                                perfect_filter_register_address+4+(mc_index * 8),
                                                0);
+                               nesadapter->pft_mcast_map[mc_index] = 255;
                        }
                }
+               /* PFT is not large enough */
+               if (multicast_addr && multicast_addr->next) {
+                       nic_active = nes_read_indexed(nesdev,
+                                               NES_IDX_NIC_MULTICAST_ALL);
+                       nic_active |= nic_active_bit;
+                       nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL,
+                                                               nic_active);
+                       nic_active = nes_read_indexed(nesdev,
+                                               NES_IDX_NIC_UNICAST_ALL);
+                       nic_active &= ~nic_active_bit;
+                       nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL,
+                                                               nic_active);
+               }
        }
+
+       spin_unlock_irqrestore(&nesadapter->resource_lock, flags);
 }
 
 
@@ -918,6 +967,10 @@ static int nes_netdev_change_mtu(struct net_device *netdev, int new_mtu)
        struct nes_device *nesdev = nesvnic->nesdev;
        int ret = 0;
        u8 jumbomode = 0;
+       u32 nic_active;
+       u32 nic_active_bit;
+       u32 uc_all_active;
+       u32 mc_all_active;
 
        if ((new_mtu < ETH_ZLEN) || (new_mtu > max_mtu))
                return -EINVAL;
@@ -931,8 +984,24 @@ static int nes_netdev_change_mtu(struct net_device *netdev, int new_mtu)
        nes_nic_init_timer_defaults(nesdev, jumbomode);
 
        if (netif_running(netdev)) {
+               nic_active_bit = 1 << nesvnic->nic_index;
+               mc_all_active = nes_read_indexed(nesdev,
+                               NES_IDX_NIC_MULTICAST_ALL) & nic_active_bit;
+               uc_all_active = nes_read_indexed(nesdev,
+                               NES_IDX_NIC_UNICAST_ALL)  & nic_active_bit;
+
                nes_netdev_stop(netdev);
                nes_netdev_open(netdev);
+
+               nic_active = nes_read_indexed(nesdev,
+                                       NES_IDX_NIC_MULTICAST_ALL);
+               nic_active |= mc_all_active;
+               nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL,
+                                                       nic_active);
+
+               nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL);
+               nic_active |= uc_all_active;
+               nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active);
        }
 
        return ret;
@@ -1208,10 +1277,12 @@ static void nes_netdev_get_drvinfo(struct net_device *netdev,
                struct ethtool_drvinfo *drvinfo)
 {
        struct nes_vnic *nesvnic = netdev_priv(netdev);
+       struct nes_adapter *nesadapter = nesvnic->nesdev->nesadapter;
 
        strcpy(drvinfo->driver, DRV_NAME);
        strcpy(drvinfo->bus_info, pci_name(nesvnic->nesdev->pcidev));
-       strcpy(drvinfo->fw_version, "TBD");
+       sprintf(drvinfo->fw_version, "%u.%u", nesadapter->firmware_version>>16,
+                               nesadapter->firmware_version & 0x000000ff);
        strcpy(drvinfo->version, DRV_VERSION);
        drvinfo->n_stats = nes_netdev_get_stats_count(netdev);
        drvinfo->testinfo_len = 0;
@@ -1587,7 +1658,9 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
                        nesvnic, (unsigned long)netdev->features, nesvnic->nic.qp_id,
                        nesvnic->nic_index, nesvnic->logical_port,  nesdev->mac_index);
 
-       if (nesvnic->nesdev->nesadapter->port_count == 1) {
+       if (nesvnic->nesdev->nesadapter->port_count == 1 &&
+               nesvnic->nesdev->nesadapter->adapter_fcn_count == 1) {
+
                nesvnic->qp_nic_index[0] = nesvnic->nic_index;
                nesvnic->qp_nic_index[1] = nesvnic->nic_index + 1;
                if (nes_drv_opt & NES_DRV_OPT_DUAL_LOGICAL_PORT) {
@@ -1598,11 +1671,14 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
                        nesvnic->qp_nic_index[3] = nesvnic->nic_index + 3;
                }
        } else {
-               if (nesvnic->nesdev->nesadapter->port_count == 2) {
-                       nesvnic->qp_nic_index[0] = nesvnic->nic_index;
-                       nesvnic->qp_nic_index[1] = nesvnic->nic_index + 2;
-                       nesvnic->qp_nic_index[2] = 0xf;
-                       nesvnic->qp_nic_index[3] = 0xf;
+               if (nesvnic->nesdev->nesadapter->port_count == 2 ||
+                       (nesvnic->nesdev->nesadapter->port_count == 1 &&
+                       nesvnic->nesdev->nesadapter->adapter_fcn_count == 2)) {
+                               nesvnic->qp_nic_index[0] = nesvnic->nic_index;
+                               nesvnic->qp_nic_index[1] = nesvnic->nic_index
+                                                                       + 2;
+                               nesvnic->qp_nic_index[2] = 0xf;
+                               nesvnic->qp_nic_index[3] = 0xf;
                } else {
                        nesvnic->qp_nic_index[0] = nesvnic->nic_index;
                        nesvnic->qp_nic_index[1] = 0xf;
index d79942e849799341e8f676f2436dacd6be2bd793..932e56fcf77413fd7f4068a25f4be24dccf22b59 100644 (file)
@@ -1467,7 +1467,6 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd,
                default:
                        nes_debug(NES_DBG_QP, "Invalid QP type: %d\n", init_attr->qp_type);
                        return ERR_PTR(-EINVAL);
-                       break;
        }
 
        /* update the QP table */
@@ -2498,7 +2497,6 @@ static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
                        nes_debug(NES_DBG_MR, "Leaving, ibmr=%p", ibmr);
 
                        return ibmr;
-                       break;
                case IWNES_MEMREG_TYPE_QP:
                case IWNES_MEMREG_TYPE_CQ:
                        nespbl = kzalloc(sizeof(*nespbl), GFP_KERNEL);
@@ -2572,7 +2570,6 @@ static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
                        nesmr->ibmr.lkey = -1;
                        nesmr->mode = req.reg_type;
                        return &nesmr->ibmr;
-                       break;
        }
 
        return ERR_PTR(-ENOSYS);
index 05eb41b8ab631692fcd46686eedc0940443236c9..68ba5c3482e47097b50998db96dc8941b37363d2 100644 (file)
@@ -268,10 +268,9 @@ struct ipoib_lro {
 };
 
 /*
- * Device private locking: tx_lock protects members used in TX fast
- * path (and we use LLTX so upper layers don't do extra locking).
- * lock protects everything else.  lock nests inside of tx_lock (ie
- * tx_lock must be acquired first if needed).
+ * Device private locking: network stack tx_lock protects members used
+ * in TX fast path, lock protects everything else.  lock nests inside
+ * of tx_lock (ie tx_lock must be acquired first if needed).
  */
 struct ipoib_dev_priv {
        spinlock_t lock;
@@ -320,7 +319,6 @@ struct ipoib_dev_priv {
 
        struct ipoib_rx_buf *rx_ring;
 
-       spinlock_t           tx_lock;
        struct ipoib_tx_buf *tx_ring;
        unsigned             tx_head;
        unsigned             tx_tail;
index 341ffedafed6704a9cb9995f49582e66c88c4505..7b14c2c395008fc2acc3b38505c81cbeb3111929 100644 (file)
@@ -786,7 +786,8 @@ void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc)
 
        dev_kfree_skb_any(tx_req->skb);
 
-       spin_lock_irqsave(&priv->tx_lock, flags);
+       netif_tx_lock(dev);
+
        ++tx->tx_tail;
        if (unlikely(--priv->tx_outstanding == ipoib_sendq_size >> 1) &&
            netif_queue_stopped(dev) &&
@@ -801,7 +802,7 @@ void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc)
                           "(status=%d, wrid=%d vend_err %x)\n",
                           wc->status, wr_id, wc->vendor_err);
 
-               spin_lock(&priv->lock);
+               spin_lock_irqsave(&priv->lock, flags);
                neigh = tx->neigh;
 
                if (neigh) {
@@ -821,10 +822,10 @@ void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc)
 
                clear_bit(IPOIB_FLAG_OPER_UP, &tx->flags);
 
-               spin_unlock(&priv->lock);
+               spin_unlock_irqrestore(&priv->lock, flags);
        }
 
-       spin_unlock_irqrestore(&priv->tx_lock, flags);
+       netif_tx_unlock(dev);
 }
 
 int ipoib_cm_dev_open(struct net_device *dev)
@@ -1149,7 +1150,6 @@ static void ipoib_cm_tx_destroy(struct ipoib_cm_tx *p)
 {
        struct ipoib_dev_priv *priv = netdev_priv(p->dev);
        struct ipoib_cm_tx_buf *tx_req;
-       unsigned long flags;
        unsigned long begin;
 
        ipoib_dbg(priv, "Destroy active connection 0x%x head 0x%x tail 0x%x\n",
@@ -1180,12 +1180,12 @@ timeout:
                                    DMA_TO_DEVICE);
                dev_kfree_skb_any(tx_req->skb);
                ++p->tx_tail;
-               spin_lock_irqsave(&priv->tx_lock, flags);
+               netif_tx_lock_bh(p->dev);
                if (unlikely(--priv->tx_outstanding == ipoib_sendq_size >> 1) &&
                    netif_queue_stopped(p->dev) &&
                    test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))
                        netif_wake_queue(p->dev);
-               spin_unlock_irqrestore(&priv->tx_lock, flags);
+               netif_tx_unlock_bh(p->dev);
        }
 
        if (p->qp)
@@ -1202,6 +1202,7 @@ static int ipoib_cm_tx_handler(struct ib_cm_id *cm_id,
        struct ipoib_dev_priv *priv = netdev_priv(tx->dev);
        struct net_device *dev = priv->dev;
        struct ipoib_neigh *neigh;
+       unsigned long flags;
        int ret;
 
        switch (event->event) {
@@ -1220,8 +1221,8 @@ static int ipoib_cm_tx_handler(struct ib_cm_id *cm_id,
        case IB_CM_REJ_RECEIVED:
        case IB_CM_TIMEWAIT_EXIT:
                ipoib_dbg(priv, "CM error %d.\n", event->event);
-               spin_lock_irq(&priv->tx_lock);
-               spin_lock(&priv->lock);
+               netif_tx_lock_bh(dev);
+               spin_lock_irqsave(&priv->lock, flags);
                neigh = tx->neigh;
 
                if (neigh) {
@@ -1239,8 +1240,8 @@ static int ipoib_cm_tx_handler(struct ib_cm_id *cm_id,
                        queue_work(ipoib_workqueue, &priv->cm.reap_task);
                }
 
-               spin_unlock(&priv->lock);
-               spin_unlock_irq(&priv->tx_lock);
+               spin_unlock_irqrestore(&priv->lock, flags);
+               netif_tx_unlock_bh(dev);
                break;
        default:
                break;
@@ -1294,19 +1295,24 @@ static void ipoib_cm_tx_start(struct work_struct *work)
        struct ib_sa_path_rec pathrec;
        u32 qpn;
 
-       spin_lock_irqsave(&priv->tx_lock, flags);
-       spin_lock(&priv->lock);
+       netif_tx_lock_bh(dev);
+       spin_lock_irqsave(&priv->lock, flags);
+
        while (!list_empty(&priv->cm.start_list)) {
                p = list_entry(priv->cm.start_list.next, typeof(*p), list);
                list_del_init(&p->list);
                neigh = p->neigh;
                qpn = IPOIB_QPN(neigh->neighbour->ha);
                memcpy(&pathrec, &p->path->pathrec, sizeof pathrec);
-               spin_unlock(&priv->lock);
-               spin_unlock_irqrestore(&priv->tx_lock, flags);
+
+               spin_unlock_irqrestore(&priv->lock, flags);
+               netif_tx_unlock_bh(dev);
+
                ret = ipoib_cm_tx_init(p, qpn, &pathrec);
-               spin_lock_irqsave(&priv->tx_lock, flags);
-               spin_lock(&priv->lock);
+
+               netif_tx_lock_bh(dev);
+               spin_lock_irqsave(&priv->lock, flags);
+
                if (ret) {
                        neigh = p->neigh;
                        if (neigh) {
@@ -1320,44 +1326,52 @@ static void ipoib_cm_tx_start(struct work_struct *work)
                        kfree(p);
                }
        }
-       spin_unlock(&priv->lock);
-       spin_unlock_irqrestore(&priv->tx_lock, flags);
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+       netif_tx_unlock_bh(dev);
 }
 
 static void ipoib_cm_tx_reap(struct work_struct *work)
 {
        struct ipoib_dev_priv *priv = container_of(work, struct ipoib_dev_priv,
                                                   cm.reap_task);
+       struct net_device *dev = priv->dev;
        struct ipoib_cm_tx *p;
+       unsigned long flags;
+
+       netif_tx_lock_bh(dev);
+       spin_lock_irqsave(&priv->lock, flags);
 
-       spin_lock_irq(&priv->tx_lock);
-       spin_lock(&priv->lock);
        while (!list_empty(&priv->cm.reap_list)) {
                p = list_entry(priv->cm.reap_list.next, typeof(*p), list);
                list_del(&p->list);
-               spin_unlock(&priv->lock);
-               spin_unlock_irq(&priv->tx_lock);
+               spin_unlock_irqrestore(&priv->lock, flags);
+               netif_tx_unlock_bh(dev);
                ipoib_cm_tx_destroy(p);
-               spin_lock_irq(&priv->tx_lock);
-               spin_lock(&priv->lock);
+               netif_tx_lock_bh(dev);
+               spin_lock_irqsave(&priv->lock, flags);
        }
-       spin_unlock(&priv->lock);
-       spin_unlock_irq(&priv->tx_lock);
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+       netif_tx_unlock_bh(dev);
 }
 
 static void ipoib_cm_skb_reap(struct work_struct *work)
 {
        struct ipoib_dev_priv *priv = container_of(work, struct ipoib_dev_priv,
                                                   cm.skb_task);
+       struct net_device *dev = priv->dev;
        struct sk_buff *skb;
-
+       unsigned long flags;
        unsigned mtu = priv->mcast_mtu;
 
-       spin_lock_irq(&priv->tx_lock);
-       spin_lock(&priv->lock);
+       netif_tx_lock_bh(dev);
+       spin_lock_irqsave(&priv->lock, flags);
+
        while ((skb = skb_dequeue(&priv->cm.skb_queue))) {
-               spin_unlock(&priv->lock);
-               spin_unlock_irq(&priv->tx_lock);
+               spin_unlock_irqrestore(&priv->lock, flags);
+               netif_tx_unlock_bh(dev);
+
                if (skb->protocol == htons(ETH_P_IP))
                        icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
@@ -1365,11 +1379,13 @@ static void ipoib_cm_skb_reap(struct work_struct *work)
                        icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, priv->dev);
 #endif
                dev_kfree_skb_any(skb);
-               spin_lock_irq(&priv->tx_lock);
-               spin_lock(&priv->lock);
+
+               netif_tx_lock_bh(dev);
+               spin_lock_irqsave(&priv->lock, flags);
        }
-       spin_unlock(&priv->lock);
-       spin_unlock_irq(&priv->tx_lock);
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+       netif_tx_unlock_bh(dev);
 }
 
 void ipoib_cm_skb_too_long(struct net_device *dev, struct sk_buff *skb,
index 66cafa20c246cea2a024fdaf1bbdaf5b6b26279d..0e748aeeae99fe830eb3c9e1c1e8bd96461ba30a 100644 (file)
@@ -468,21 +468,22 @@ void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr)
 static void drain_tx_cq(struct net_device *dev)
 {
        struct ipoib_dev_priv *priv = netdev_priv(dev);
-       unsigned long flags;
 
-       spin_lock_irqsave(&priv->tx_lock, flags);
+       netif_tx_lock(dev);
        while (poll_tx(priv))
                ; /* nothing */
 
        if (netif_queue_stopped(dev))
                mod_timer(&priv->poll_timer, jiffies + 1);
 
-       spin_unlock_irqrestore(&priv->tx_lock, flags);
+       netif_tx_unlock(dev);
 }
 
 void ipoib_send_comp_handler(struct ib_cq *cq, void *dev_ptr)
 {
-       drain_tx_cq((struct net_device *)dev_ptr);
+       struct ipoib_dev_priv *priv = netdev_priv(dev_ptr);
+
+       mod_timer(&priv->poll_timer, jiffies);
 }
 
 static inline int post_send(struct ipoib_dev_priv *priv,
@@ -614,17 +615,20 @@ static void __ipoib_reap_ah(struct net_device *dev)
        struct ipoib_dev_priv *priv = netdev_priv(dev);
        struct ipoib_ah *ah, *tah;
        LIST_HEAD(remove_list);
+       unsigned long flags;
+
+       netif_tx_lock_bh(dev);
+       spin_lock_irqsave(&priv->lock, flags);
 
-       spin_lock_irq(&priv->tx_lock);
-       spin_lock(&priv->lock);
        list_for_each_entry_safe(ah, tah, &priv->dead_ahs, list)
                if ((int) priv->tx_tail - (int) ah->last_send >= 0) {
                        list_del(&ah->list);
                        ib_destroy_ah(ah->ah);
                        kfree(ah);
                }
-       spin_unlock(&priv->lock);
-       spin_unlock_irq(&priv->tx_lock);
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+       netif_tx_unlock_bh(dev);
 }
 
 void ipoib_reap_ah(struct work_struct *work)
@@ -761,6 +765,14 @@ void ipoib_drain_cq(struct net_device *dev)
 {
        struct ipoib_dev_priv *priv = netdev_priv(dev);
        int i, n;
+
+       /*
+        * We call completion handling routines that expect to be
+        * called from the BH-disabled NAPI poll context, so disable
+        * BHs here too.
+        */
+       local_bh_disable();
+
        do {
                n = ib_poll_cq(priv->recv_cq, IPOIB_NUM_WC, priv->ibwc);
                for (i = 0; i < n; ++i) {
@@ -784,6 +796,8 @@ void ipoib_drain_cq(struct net_device *dev)
 
        while (poll_tx(priv))
                ; /* nothing */
+
+       local_bh_enable();
 }
 
 int ipoib_ib_dev_stop(struct net_device *dev, int flush)
index e9ca3cb57d5219960f9f67adf7eadb19dabc206e..c0ee514396dfa7a18842d0503d2c01641661d261 100644 (file)
@@ -373,9 +373,10 @@ void ipoib_flush_paths(struct net_device *dev)
        struct ipoib_dev_priv *priv = netdev_priv(dev);
        struct ipoib_path *path, *tp;
        LIST_HEAD(remove_list);
+       unsigned long flags;
 
-       spin_lock_irq(&priv->tx_lock);
-       spin_lock(&priv->lock);
+       netif_tx_lock_bh(dev);
+       spin_lock_irqsave(&priv->lock, flags);
 
        list_splice_init(&priv->path_list, &remove_list);
 
@@ -385,15 +386,16 @@ void ipoib_flush_paths(struct net_device *dev)
        list_for_each_entry_safe(path, tp, &remove_list, list) {
                if (path->query)
                        ib_sa_cancel_query(path->query_id, path->query);
-               spin_unlock(&priv->lock);
-               spin_unlock_irq(&priv->tx_lock);
+               spin_unlock_irqrestore(&priv->lock, flags);
+               netif_tx_unlock_bh(dev);
                wait_for_completion(&path->done);
                path_free(dev, path);
-               spin_lock_irq(&priv->tx_lock);
-               spin_lock(&priv->lock);
+               netif_tx_lock_bh(dev);
+               spin_lock_irqsave(&priv->lock, flags);
        }
-       spin_unlock(&priv->lock);
-       spin_unlock_irq(&priv->tx_lock);
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+       netif_tx_unlock_bh(dev);
 }
 
 static void path_rec_completion(int status,
@@ -555,6 +557,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
        struct ipoib_dev_priv *priv = netdev_priv(dev);
        struct ipoib_path *path;
        struct ipoib_neigh *neigh;
+       unsigned long flags;
 
        neigh = ipoib_neigh_alloc(skb->dst->neighbour, skb->dev);
        if (!neigh) {
@@ -563,11 +566,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
                return;
        }
 
-       /*
-        * We can only be called from ipoib_start_xmit, so we're
-        * inside tx_lock -- no need to save/restore flags.
-        */
-       spin_lock(&priv->lock);
+       spin_lock_irqsave(&priv->lock, flags);
 
        path = __path_find(dev, skb->dst->neighbour->ha + 4);
        if (!path) {
@@ -614,7 +613,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
                __skb_queue_tail(&neigh->queue, skb);
        }
 
-       spin_unlock(&priv->lock);
+       spin_unlock_irqrestore(&priv->lock, flags);
        return;
 
 err_list:
@@ -626,7 +625,7 @@ err_drop:
        ++dev->stats.tx_dropped;
        dev_kfree_skb_any(skb);
 
-       spin_unlock(&priv->lock);
+       spin_unlock_irqrestore(&priv->lock, flags);
 }
 
 static void ipoib_path_lookup(struct sk_buff *skb, struct net_device *dev)
@@ -650,12 +649,9 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
 {
        struct ipoib_dev_priv *priv = netdev_priv(dev);
        struct ipoib_path *path;
+       unsigned long flags;
 
-       /*
-        * We can only be called from ipoib_start_xmit, so we're
-        * inside tx_lock -- no need to save/restore flags.
-        */
-       spin_lock(&priv->lock);
+       spin_lock_irqsave(&priv->lock, flags);
 
        path = __path_find(dev, phdr->hwaddr + 4);
        if (!path || !path->valid) {
@@ -667,7 +663,7 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
                        __skb_queue_tail(&path->queue, skb);
 
                        if (path_rec_start(dev, path)) {
-                               spin_unlock(&priv->lock);
+                               spin_unlock_irqrestore(&priv->lock, flags);
                                path_free(dev, path);
                                return;
                        } else
@@ -677,7 +673,7 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
                        dev_kfree_skb_any(skb);
                }
 
-               spin_unlock(&priv->lock);
+               spin_unlock_irqrestore(&priv->lock, flags);
                return;
        }
 
@@ -696,7 +692,7 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
                dev_kfree_skb_any(skb);
        }
 
-       spin_unlock(&priv->lock);
+       spin_unlock_irqrestore(&priv->lock, flags);
 }
 
 static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
@@ -705,13 +701,10 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
        struct ipoib_neigh *neigh;
        unsigned long flags;
 
-       if (unlikely(!spin_trylock_irqsave(&priv->tx_lock, flags)))
-               return NETDEV_TX_LOCKED;
-
        if (likely(skb->dst && skb->dst->neighbour)) {
                if (unlikely(!*to_ipoib_neigh(skb->dst->neighbour))) {
                        ipoib_path_lookup(skb, dev);
-                       goto out;
+                       return NETDEV_TX_OK;
                }
 
                neigh = *to_ipoib_neigh(skb->dst->neighbour);
@@ -721,7 +714,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
                                            skb->dst->neighbour->ha + 4,
                                            sizeof(union ib_gid))) ||
                                         (neigh->dev != dev))) {
-                               spin_lock(&priv->lock);
+                               spin_lock_irqsave(&priv->lock, flags);
                                /*
                                 * It's safe to call ipoib_put_ah() inside
                                 * priv->lock here, because we know that
@@ -732,25 +725,25 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
                                ipoib_put_ah(neigh->ah);
                                list_del(&neigh->list);
                                ipoib_neigh_free(dev, neigh);
-                               spin_unlock(&priv->lock);
+                               spin_unlock_irqrestore(&priv->lock, flags);
                                ipoib_path_lookup(skb, dev);
-                               goto out;
+                               return NETDEV_TX_OK;
                        }
 
                if (ipoib_cm_get(neigh)) {
                        if (ipoib_cm_up(neigh)) {
                                ipoib_cm_send(dev, skb, ipoib_cm_get(neigh));
-                               goto out;
+                               return NETDEV_TX_OK;
                        }
                } else if (neigh->ah) {
                        ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(skb->dst->neighbour->ha));
-                       goto out;
+                       return NETDEV_TX_OK;
                }
 
                if (skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE) {
-                       spin_lock(&priv->lock);
+                       spin_lock_irqsave(&priv->lock, flags);
                        __skb_queue_tail(&neigh->queue, skb);
-                       spin_unlock(&priv->lock);
+                       spin_unlock_irqrestore(&priv->lock, flags);
                } else {
                        ++dev->stats.tx_dropped;
                        dev_kfree_skb_any(skb);
@@ -779,16 +772,13 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
                                           IPOIB_GID_RAW_ARG(phdr->hwaddr + 4));
                                dev_kfree_skb_any(skb);
                                ++dev->stats.tx_dropped;
-                               goto out;
+                               return NETDEV_TX_OK;
                        }
 
                        unicast_arp_send(skb, dev, phdr);
                }
        }
 
-out:
-       spin_unlock_irqrestore(&priv->tx_lock, flags);
-
        return NETDEV_TX_OK;
 }
 
@@ -1052,7 +1042,6 @@ static void ipoib_setup(struct net_device *dev)
        dev->type                = ARPHRD_INFINIBAND;
        dev->tx_queue_len        = ipoib_sendq_size * 2;
        dev->features            = (NETIF_F_VLAN_CHALLENGED     |
-                                   NETIF_F_LLTX                |
                                    NETIF_F_HIGHDMA);
 
        memcpy(dev->broadcast, ipv4_bcast_addr, INFINIBAND_ALEN);
@@ -1064,7 +1053,6 @@ static void ipoib_setup(struct net_device *dev)
        ipoib_lro_setup(priv);
 
        spin_lock_init(&priv->lock);
-       spin_lock_init(&priv->tx_lock);
 
        mutex_init(&priv->vlan_mutex);
 
index aae28620a6e5f01a3650ce59b5c8d35f65b4ca28..d9d1223c3fd5f7dc1609764c9a1db16e3a20018f 100644 (file)
@@ -69,14 +69,13 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast)
        struct net_device *dev = mcast->dev;
        struct ipoib_dev_priv *priv = netdev_priv(dev);
        struct ipoib_neigh *neigh, *tmp;
-       unsigned long flags;
        int tx_dropped = 0;
 
        ipoib_dbg_mcast(netdev_priv(dev),
                        "deleting multicast group " IPOIB_GID_FMT "\n",
                        IPOIB_GID_ARG(mcast->mcmember.mgid));
 
-       spin_lock_irqsave(&priv->lock, flags);
+       spin_lock_irq(&priv->lock);
 
        list_for_each_entry_safe(neigh, tmp, &mcast->neigh_list, list) {
                /*
@@ -90,7 +89,7 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast)
                ipoib_neigh_free(dev, neigh);
        }
 
-       spin_unlock_irqrestore(&priv->lock, flags);
+       spin_unlock_irq(&priv->lock);
 
        if (mcast->ah)
                ipoib_put_ah(mcast->ah);
@@ -100,9 +99,9 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast)
                dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue));
        }
 
-       spin_lock_irqsave(&priv->tx_lock, flags);
+       netif_tx_lock_bh(dev);
        dev->stats.tx_dropped += tx_dropped;
-       spin_unlock_irqrestore(&priv->tx_lock, flags);
+       netif_tx_unlock_bh(dev);
 
        kfree(mcast);
 }
@@ -259,10 +258,10 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
        }
 
        /* actually send any queued packets */
-       spin_lock_irq(&priv->tx_lock);
+       netif_tx_lock_bh(dev);
        while (!skb_queue_empty(&mcast->pkt_queue)) {
                struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue);
-               spin_unlock_irq(&priv->tx_lock);
+               netif_tx_unlock_bh(dev);
 
                skb->dev = dev;
 
@@ -273,9 +272,9 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
 
                if (dev_queue_xmit(skb))
                        ipoib_warn(priv, "dev_queue_xmit failed to requeue packet\n");
-               spin_lock_irq(&priv->tx_lock);
+               netif_tx_lock_bh(dev);
        }
-       spin_unlock_irq(&priv->tx_lock);
+       netif_tx_unlock_bh(dev);
 
        return 0;
 }
@@ -286,7 +285,6 @@ ipoib_mcast_sendonly_join_complete(int status,
 {
        struct ipoib_mcast *mcast = multicast->context;
        struct net_device *dev = mcast->dev;
-       struct ipoib_dev_priv *priv = netdev_priv(dev);
 
        /* We trap for port events ourselves. */
        if (status == -ENETRESET)
@@ -302,12 +300,12 @@ ipoib_mcast_sendonly_join_complete(int status,
                                        IPOIB_GID_ARG(mcast->mcmember.mgid), status);
 
                /* Flush out any queued packets */
-               spin_lock_irq(&priv->tx_lock);
+               netif_tx_lock_bh(dev);
                while (!skb_queue_empty(&mcast->pkt_queue)) {
                        ++dev->stats.tx_dropped;
                        dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue));
                }
-               spin_unlock_irq(&priv->tx_lock);
+               netif_tx_unlock_bh(dev);
 
                /* Clear the busy flag so we try again */
                status = test_and_clear_bit(IPOIB_MCAST_FLAG_BUSY,
@@ -662,12 +660,9 @@ void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb)
 {
        struct ipoib_dev_priv *priv = netdev_priv(dev);
        struct ipoib_mcast *mcast;
+       unsigned long flags;
 
-       /*
-        * We can only be called from ipoib_start_xmit, so we're
-        * inside tx_lock -- no need to save/restore flags.
-        */
-       spin_lock(&priv->lock);
+       spin_lock_irqsave(&priv->lock, flags);
 
        if (!test_bit(IPOIB_FLAG_OPER_UP, &priv->flags)         ||
            !priv->broadcast                                    ||
@@ -738,7 +733,7 @@ out:
        }
 
 unlock:
-       spin_unlock(&priv->lock);
+       spin_unlock_irqrestore(&priv->lock, flags);
 }
 
 void ipoib_mcast_dev_flush(struct net_device *dev)
index 13956437bc81888d38e89ba2abbaa8d62772fc52..682ef9e6acd3344d5bf8a19f4550de90331f37d3 100644 (file)
@@ -333,7 +333,6 @@ static void crypt_convert_init(struct crypt_config *cc,
        ctx->idx_out = bio_out ? bio_out->bi_idx : 0;
        ctx->sector = sector + cc->iv_offset;
        init_completion(&ctx->restart);
-       atomic_set(&ctx->pending, 1);
 }
 
 static int crypt_convert_block(struct crypt_config *cc,
@@ -408,6 +407,8 @@ static int crypt_convert(struct crypt_config *cc,
 {
        int r;
 
+       atomic_set(&ctx->pending, 1);
+
        while(ctx->idx_in < ctx->bio_in->bi_vcnt &&
              ctx->idx_out < ctx->bio_out->bi_vcnt) {
 
@@ -456,9 +457,11 @@ static void dm_crypt_bio_destructor(struct bio *bio)
 /*
  * Generate a new unfragmented bio with the given size
  * This should never violate the device limitations
- * May return a smaller bio when running out of pages
+ * May return a smaller bio when running out of pages, indicated by
+ * *out_of_pages set to 1.
  */
-static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned size)
+static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned size,
+                                     unsigned *out_of_pages)
 {
        struct crypt_config *cc = io->target->private;
        struct bio *clone;
@@ -472,11 +475,14 @@ static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned size)
                return NULL;
 
        clone_init(io, clone);
+       *out_of_pages = 0;
 
        for (i = 0; i < nr_iovecs; i++) {
                page = mempool_alloc(cc->page_pool, gfp_mask);
-               if (!page)
+               if (!page) {
+                       *out_of_pages = 1;
                        break;
+               }
 
                /*
                 * if additional pages cannot be allocated without waiting,
@@ -517,6 +523,27 @@ static void crypt_free_buffer_pages(struct crypt_config *cc, struct bio *clone)
        }
 }
 
+static struct dm_crypt_io *crypt_io_alloc(struct dm_target *ti,
+                                         struct bio *bio, sector_t sector)
+{
+       struct crypt_config *cc = ti->private;
+       struct dm_crypt_io *io;
+
+       io = mempool_alloc(cc->io_pool, GFP_NOIO);
+       io->target = ti;
+       io->base_bio = bio;
+       io->sector = sector;
+       io->error = 0;
+       atomic_set(&io->pending, 0);
+
+       return io;
+}
+
+static void crypt_inc_pending(struct dm_crypt_io *io)
+{
+       atomic_inc(&io->pending);
+}
+
 /*
  * One of the bios was finished. Check for completion of
  * the whole request and correctly clean up the buffer.
@@ -591,7 +618,7 @@ static void kcryptd_io_read(struct dm_crypt_io *io)
        struct bio *base_bio = io->base_bio;
        struct bio *clone;
 
-       atomic_inc(&io->pending);
+       crypt_inc_pending(io);
 
        /*
         * The block layer might modify the bvec array, so always
@@ -653,6 +680,7 @@ static void kcryptd_crypt_write_io_submit(struct dm_crypt_io *io,
                crypt_free_buffer_pages(cc, clone);
                bio_put(clone);
                io->error = -EIO;
+               crypt_dec_pending(io);
                return;
        }
 
@@ -664,28 +692,34 @@ static void kcryptd_crypt_write_io_submit(struct dm_crypt_io *io,
 
        if (async)
                kcryptd_queue_io(io);
-       else {
-               atomic_inc(&io->pending);
+       else
                generic_make_request(clone);
-       }
 }
 
-static void kcryptd_crypt_write_convert_loop(struct dm_crypt_io *io)
+static void kcryptd_crypt_write_convert(struct dm_crypt_io *io)
 {
        struct crypt_config *cc = io->target->private;
        struct bio *clone;
+       int crypt_finished;
+       unsigned out_of_pages = 0;
        unsigned remaining = io->base_bio->bi_size;
        int r;
 
+       /*
+        * Prevent io from disappearing until this function completes.
+        */
+       crypt_inc_pending(io);
+       crypt_convert_init(cc, &io->ctx, NULL, io->base_bio, io->sector);
+
        /*
         * The allocated buffers can be smaller than the whole bio,
         * so repeat the whole process until all the data can be handled.
         */
        while (remaining) {
-               clone = crypt_alloc_buffer(io, remaining);
+               clone = crypt_alloc_buffer(io, remaining, &out_of_pages);
                if (unlikely(!clone)) {
                        io->error = -ENOMEM;
-                       return;
+                       break;
                }
 
                io->ctx.bio_out = clone;
@@ -693,37 +727,32 @@ static void kcryptd_crypt_write_convert_loop(struct dm_crypt_io *io)
 
                remaining -= clone->bi_size;
 
+               crypt_inc_pending(io);
                r = crypt_convert(cc, &io->ctx);
+               crypt_finished = atomic_dec_and_test(&io->ctx.pending);
 
-               if (atomic_dec_and_test(&io->ctx.pending)) {
-                       /* processed, no running async crypto  */
+               /* Encryption was already finished, submit io now */
+               if (crypt_finished) {
                        kcryptd_crypt_write_io_submit(io, r, 0);
-                       if (unlikely(r < 0))
-                               return;
-               } else
-                       atomic_inc(&io->pending);
 
-               /* out of memory -> run queues */
-               if (unlikely(remaining)) {
-                       /* wait for async crypto then reinitialize pending */
-                       wait_event(cc->writeq, !atomic_read(&io->ctx.pending));
-                       atomic_set(&io->ctx.pending, 1);
-                       congestion_wait(WRITE, HZ/100);
+                       /*
+                        * If there was an error, do not try next fragments.
+                        * For async, error is processed in async handler.
+                        */
+                       if (unlikely(r < 0))
+                               break;
                }
-       }
-}
 
-static void kcryptd_crypt_write_convert(struct dm_crypt_io *io)
-{
-       struct crypt_config *cc = io->target->private;
-
-       /*
-        * Prevent io from disappearing until this function completes.
-        */
-       atomic_inc(&io->pending);
+               /*
+                * Out of memory -> run queues
+                * But don't wait if split was due to the io size restriction
+                */
+               if (unlikely(out_of_pages))
+                       congestion_wait(WRITE, HZ/100);
 
-       crypt_convert_init(cc, &io->ctx, NULL, io->base_bio, io->sector);
-       kcryptd_crypt_write_convert_loop(io);
+               if (unlikely(remaining))
+                       wait_event(cc->writeq, !atomic_read(&io->ctx.pending));
+       }
 
        crypt_dec_pending(io);
 }
@@ -741,7 +770,7 @@ static void kcryptd_crypt_read_convert(struct dm_crypt_io *io)
        struct crypt_config *cc = io->target->private;
        int r = 0;
 
-       atomic_inc(&io->pending);
+       crypt_inc_pending(io);
 
        crypt_convert_init(cc, &io->ctx, io->base_bio, io->base_bio,
                           io->sector);
@@ -1108,15 +1137,9 @@ static void crypt_dtr(struct dm_target *ti)
 static int crypt_map(struct dm_target *ti, struct bio *bio,
                     union map_info *map_context)
 {
-       struct crypt_config *cc = ti->private;
        struct dm_crypt_io *io;
 
-       io = mempool_alloc(cc->io_pool, GFP_NOIO);
-       io->target = ti;
-       io->base_bio = bio;
-       io->sector = bio->bi_sector - ti->begin;
-       io->error = 0;
-       atomic_set(&io->pending, 0);
+       io = crypt_io_alloc(ti, bio, bio->bi_sector - ti->begin);
 
        if (bio_data_dir(io->base_bio) == READ)
                kcryptd_queue_io(io);
index 41f408068a7c9c2329c61eb7e3eb47a82af6e280..769ab677f8e05a4b3887093be5e98e0cf9cd4125 100644 (file)
@@ -108,12 +108,12 @@ struct pstore {
         * Used to keep track of which metadata area the data in
         * 'chunk' refers to.
         */
-       uint32_t current_area;
+       chunk_t current_area;
 
        /*
         * The next free chunk for an exception.
         */
-       uint32_t next_free;
+       chunk_t next_free;
 
        /*
         * The index of next free exception in the current
@@ -175,7 +175,7 @@ static void do_metadata(struct work_struct *work)
 /*
  * Read or write a chunk aligned and sized block of data from a device.
  */
-static int chunk_io(struct pstore *ps, uint32_t chunk, int rw, int metadata)
+static int chunk_io(struct pstore *ps, chunk_t chunk, int rw, int metadata)
 {
        struct dm_io_region where = {
                .bdev = ps->snap->cow->bdev,
@@ -208,17 +208,24 @@ static int chunk_io(struct pstore *ps, uint32_t chunk, int rw, int metadata)
        return req.result;
 }
 
+/*
+ * Convert a metadata area index to a chunk index.
+ */
+static chunk_t area_location(struct pstore *ps, chunk_t area)
+{
+       return 1 + ((ps->exceptions_per_area + 1) * area);
+}
+
 /*
  * Read or write a metadata area.  Remembering to skip the first
  * chunk which holds the header.
  */
-static int area_io(struct pstore *ps, uint32_t area, int rw)
+static int area_io(struct pstore *ps, chunk_t area, int rw)
 {
        int r;
-       uint32_t chunk;
+       chunk_t chunk;
 
-       /* convert a metadata area index to a chunk index */
-       chunk = 1 + ((ps->exceptions_per_area + 1) * area);
+       chunk = area_location(ps, area);
 
        r = chunk_io(ps, chunk, rw, 0);
        if (r)
@@ -228,7 +235,7 @@ static int area_io(struct pstore *ps, uint32_t area, int rw)
        return 0;
 }
 
-static int zero_area(struct pstore *ps, uint32_t area)
+static int zero_area(struct pstore *ps, chunk_t area)
 {
        memset(ps->area, 0, ps->snap->chunk_size << SECTOR_SHIFT);
        return area_io(ps, area, WRITE);
@@ -404,7 +411,7 @@ static int insert_exceptions(struct pstore *ps, int *full)
 
 static int read_exceptions(struct pstore *ps)
 {
-       uint32_t area;
+       chunk_t area;
        int r, full = 1;
 
        /*
@@ -517,6 +524,7 @@ static int persistent_prepare(struct exception_store *store,
 {
        struct pstore *ps = get_info(store);
        uint32_t stride;
+       chunk_t next_free;
        sector_t size = get_dev_size(store->snap->cow->bdev);
 
        /* Is there enough room ? */
@@ -530,7 +538,8 @@ static int persistent_prepare(struct exception_store *store,
         * into account the location of the metadata chunks.
         */
        stride = (ps->exceptions_per_area + 1);
-       if ((++ps->next_free % stride) == 1)
+       next_free = ++ps->next_free;
+       if (sector_div(next_free, stride) == 1)
                ps->next_free++;
 
        atomic_inc(&ps->pending_count);
index b262c0042de3f79394d7ff46c61e36b68da29e48..dca401dc70a0ec3f24c0392851a002a8a125fd21 100644 (file)
@@ -426,7 +426,7 @@ static int list_devices(struct dm_ioctl *param, size_t param_size)
                                old_nl->next = (uint32_t) ((void *) nl -
                                                           (void *) old_nl);
                        disk = dm_disk(hc->md);
-                       nl->dev = huge_encode_dev(MKDEV(disk->major, disk->first_minor));
+                       nl->dev = huge_encode_dev(disk_devt(disk));
                        nl->next = 0;
                        strcpy(nl->name, hc->name);
 
@@ -539,7 +539,7 @@ static int __dev_status(struct mapped_device *md, struct dm_ioctl *param)
        if (dm_suspended(md))
                param->flags |= DM_SUSPEND_FLAG;
 
-       param->dev = huge_encode_dev(MKDEV(disk->major, disk->first_minor));
+       param->dev = huge_encode_dev(disk_devt(disk));
 
        /*
         * Yes, this will be out of date by the time it gets back
@@ -548,7 +548,7 @@ static int __dev_status(struct mapped_device *md, struct dm_ioctl *param)
         */
        param->open_count = dm_open_count(md);
 
-       if (disk->policy)
+       if (get_disk_ro(disk))
                param->flags |= DM_READONLY_FLAG;
 
        param->event_nr = dm_get_event_nr(md);
@@ -1131,7 +1131,7 @@ static void retrieve_deps(struct dm_table *table,
        unsigned int count = 0;
        struct list_head *tmp;
        size_t len, needed;
-       struct dm_dev *dd;
+       struct dm_dev_internal *dd;
        struct dm_target_deps *deps;
 
        deps = get_result_buffer(param, param_size, &len);
@@ -1157,7 +1157,7 @@ static void retrieve_deps(struct dm_table *table,
        deps->count = count;
        count = 0;
        list_for_each_entry (dd, dm_table_get_devices(table), list)
-               deps->dev[count++] = huge_encode_dev(dd->bdev->bd_dev);
+               deps->dev[count++] = huge_encode_dev(dd->dm_dev.bdev->bd_dev);
 
        param->data_size = param->data_start + needed;
 }
index c2fcf28b4c7022b2ec66e0c9d661e8a87b5279c8..103304c1e3b06899d8277cd95369e3df94da36db 100644 (file)
@@ -30,9 +30,11 @@ struct pgpath {
        struct list_head list;
 
        struct priority_group *pg;      /* Owning PG */
+       unsigned is_active;             /* Path status */
        unsigned fail_count;            /* Cumulative failure count */
 
        struct dm_path path;
+       struct work_struct deactivate_path;
 };
 
 #define path_to_pgpath(__pgp) container_of((__pgp), struct pgpath, path)
@@ -112,6 +114,7 @@ static struct workqueue_struct *kmultipathd, *kmpath_handlerd;
 static void process_queued_ios(struct work_struct *work);
 static void trigger_event(struct work_struct *work);
 static void activate_path(struct work_struct *work);
+static void deactivate_path(struct work_struct *work);
 
 
 /*-----------------------------------------------
@@ -122,8 +125,10 @@ static struct pgpath *alloc_pgpath(void)
 {
        struct pgpath *pgpath = kzalloc(sizeof(*pgpath), GFP_KERNEL);
 
-       if (pgpath)
-               pgpath->path.is_active = 1;
+       if (pgpath) {
+               pgpath->is_active = 1;
+               INIT_WORK(&pgpath->deactivate_path, deactivate_path);
+       }
 
        return pgpath;
 }
@@ -133,6 +138,14 @@ static void free_pgpath(struct pgpath *pgpath)
        kfree(pgpath);
 }
 
+static void deactivate_path(struct work_struct *work)
+{
+       struct pgpath *pgpath =
+               container_of(work, struct pgpath, deactivate_path);
+
+       blk_abort_queue(pgpath->path.dev->bdev->bd_disk->queue);
+}
+
 static struct priority_group *alloc_priority_group(void)
 {
        struct priority_group *pg;
@@ -563,12 +576,12 @@ static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps,
        /* we need at least a path arg */
        if (as->argc < 1) {
                ti->error = "no device given";
-               return NULL;
+               return ERR_PTR(-EINVAL);
        }
 
        p = alloc_pgpath();
        if (!p)
-               return NULL;
+               return ERR_PTR(-ENOMEM);
 
        r = dm_get_device(ti, shift(as), ti->begin, ti->len,
                          dm_table_get_mode(ti->table), &p->path.dev);
@@ -596,7 +609,7 @@ static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps,
 
  bad:
        free_pgpath(p);
-       return NULL;
+       return ERR_PTR(r);
 }
 
 static struct priority_group *parse_priority_group(struct arg_set *as,
@@ -614,14 +627,14 @@ static struct priority_group *parse_priority_group(struct arg_set *as,
 
        if (as->argc < 2) {
                as->argc = 0;
-               ti->error = "not enough priority group aruments";
-               return NULL;
+               ti->error = "not enough priority group arguments";
+               return ERR_PTR(-EINVAL);
        }
 
        pg = alloc_priority_group();
        if (!pg) {
                ti->error = "couldn't allocate priority group";
-               return NULL;
+               return ERR_PTR(-ENOMEM);
        }
        pg->m = m;
 
@@ -654,8 +667,10 @@ static struct priority_group *parse_priority_group(struct arg_set *as,
                path_args.argv = as->argv;
 
                pgpath = parse_path(&path_args, &pg->ps, ti);
-               if (!pgpath)
+               if (IS_ERR(pgpath)) {
+                       r = PTR_ERR(pgpath);
                        goto bad;
+               }
 
                pgpath->pg = pg;
                list_add_tail(&pgpath->list, &pg->pgpaths);
@@ -666,7 +681,7 @@ static struct priority_group *parse_priority_group(struct arg_set *as,
 
  bad:
        free_priority_group(pg, ti);
-       return NULL;
+       return ERR_PTR(r);
 }
 
 static int parse_hw_handler(struct arg_set *as, struct multipath *m)
@@ -785,8 +800,8 @@ static int multipath_ctr(struct dm_target *ti, unsigned int argc,
                struct priority_group *pg;
 
                pg = parse_priority_group(&as, m);
-               if (!pg) {
-                       r = -EINVAL;
+               if (IS_ERR(pg)) {
+                       r = PTR_ERR(pg);
                        goto bad;
                }
 
@@ -852,13 +867,13 @@ static int fail_path(struct pgpath *pgpath)
 
        spin_lock_irqsave(&m->lock, flags);
 
-       if (!pgpath->path.is_active)
+       if (!pgpath->is_active)
                goto out;
 
        DMWARN("Failing path %s.", pgpath->path.dev->name);
 
        pgpath->pg->ps.type->fail_path(&pgpath->pg->ps, &pgpath->path);
-       pgpath->path.is_active = 0;
+       pgpath->is_active = 0;
        pgpath->fail_count++;
 
        m->nr_valid_paths--;
@@ -870,6 +885,7 @@ static int fail_path(struct pgpath *pgpath)
                      pgpath->path.dev->name, m->nr_valid_paths);
 
        queue_work(kmultipathd, &m->trigger_event);
+       queue_work(kmultipathd, &pgpath->deactivate_path);
 
 out:
        spin_unlock_irqrestore(&m->lock, flags);
@@ -888,7 +904,7 @@ static int reinstate_path(struct pgpath *pgpath)
 
        spin_lock_irqsave(&m->lock, flags);
 
-       if (pgpath->path.is_active)
+       if (pgpath->is_active)
                goto out;
 
        if (!pgpath->pg->ps.type->reinstate_path) {
@@ -902,7 +918,7 @@ static int reinstate_path(struct pgpath *pgpath)
        if (r)
                goto out;
 
-       pgpath->path.is_active = 1;
+       pgpath->is_active = 1;
 
        m->current_pgpath = NULL;
        if (!m->nr_valid_paths++ && m->queue_size)
@@ -1290,7 +1306,7 @@ static int multipath_status(struct dm_target *ti, status_type_t type,
 
                        list_for_each_entry(p, &pg->pgpaths, list) {
                                DMEMIT("%s %s %u ", p->path.dev->name,
-                                      p->path.is_active ? "A" : "F",
+                                      p->is_active ? "A" : "F",
                                       p->fail_count);
                                if (pg->ps.type->status)
                                        sz += pg->ps.type->status(&pg->ps,
index c198b856a452540ebb47e9718458e39b7c6113c3..e230f7196259622947a6bfc5169328a41ed15223 100644 (file)
@@ -13,8 +13,6 @@ struct dm_dev;
 
 struct dm_path {
        struct dm_dev *dev;     /* Read-only */
-       unsigned is_active;     /* Read-only */
-
        void *pscontext;        /* For path-selector use */
 };
 
index ff05fe89308313ab5792a6b3dc9146db3e585c6a..29913e42c4ab436da84fc7fdf6e42da4fe051e49 100644 (file)
@@ -842,7 +842,9 @@ static int recover(struct mirror_set *ms, struct region *reg)
        }
 
        /* hand to kcopyd */
-       set_bit(DM_KCOPYD_IGNORE_ERROR, &flags);
+       if (!errors_handled(ms))
+               set_bit(DM_KCOPYD_IGNORE_ERROR, &flags);
+
        r = dm_kcopyd_copy(ms->kcopyd_client, &from, ms->nr_mirrors - 1, to,
                           flags, recovery_complete, reg);
 
index 4de90ab3968b3f9528420281a9398a9bf11ec8e7..b745d8ac625b5ffd6730f585e95fec2081cf8429 100644 (file)
@@ -284,8 +284,8 @@ static int stripe_end_io(struct dm_target *ti, struct bio *bio,
 
        memset(major_minor, 0, sizeof(major_minor));
        sprintf(major_minor, "%d:%d",
-               bio->bi_bdev->bd_disk->major,
-               bio->bi_bdev->bd_disk->first_minor);
+               MAJOR(disk_devt(bio->bi_bdev->bd_disk)),
+               MINOR(disk_devt(bio->bi_bdev->bd_disk)));
 
        /*
         * Test to see which stripe drive triggered the event
index 61f441409234e334048460bd6475eee2572d883c..a740a6950f598ce44eb7ee285b48f057ef19cd83 100644 (file)
@@ -250,7 +250,8 @@ static void free_devices(struct list_head *devices)
        struct list_head *tmp, *next;
 
        list_for_each_safe(tmp, next, devices) {
-               struct dm_dev *dd = list_entry(tmp, struct dm_dev, list);
+               struct dm_dev_internal *dd =
+                   list_entry(tmp, struct dm_dev_internal, list);
                kfree(dd);
        }
 }
@@ -327,12 +328,12 @@ static int lookup_device(const char *path, dev_t *dev)
 /*
  * See if we've already got a device in the list.
  */
-static struct dm_dev *find_device(struct list_head *l, dev_t dev)
+static struct dm_dev_internal *find_device(struct list_head *l, dev_t dev)
 {
-       struct dm_dev *dd;
+       struct dm_dev_internal *dd;
 
        list_for_each_entry (dd, l, list)
-               if (dd->bdev->bd_dev == dev)
+               if (dd->dm_dev.bdev->bd_dev == dev)
                        return dd;
 
        return NULL;
@@ -341,45 +342,47 @@ static struct dm_dev *find_device(struct list_head *l, dev_t dev)
 /*
  * Open a device so we can use it as a map destination.
  */
-static int open_dev(struct dm_dev *d, dev_t dev, struct mapped_device *md)
+static int open_dev(struct dm_dev_internal *d, dev_t dev,
+                   struct mapped_device *md)
 {
        static char *_claim_ptr = "I belong to device-mapper";
        struct block_device *bdev;
 
        int r;
 
-       BUG_ON(d->bdev);
+       BUG_ON(d->dm_dev.bdev);
 
-       bdev = open_by_devnum(dev, d->mode);
+       bdev = open_by_devnum(dev, d->dm_dev.mode);
        if (IS_ERR(bdev))
                return PTR_ERR(bdev);
        r = bd_claim_by_disk(bdev, _claim_ptr, dm_disk(md));
        if (r)
                blkdev_put(bdev);
        else
-               d->bdev = bdev;
+               d->dm_dev.bdev = bdev;
        return r;
 }
 
 /*
  * Close a device that we've been using.
  */
-static void close_dev(struct dm_dev *d, struct mapped_device *md)
+static void close_dev(struct dm_dev_internal *d, struct mapped_device *md)
 {
-       if (!d->bdev)
+       if (!d->dm_dev.bdev)
                return;
 
-       bd_release_from_disk(d->bdev, dm_disk(md));
-       blkdev_put(d->bdev);
-       d->bdev = NULL;
+       bd_release_from_disk(d->dm_dev.bdev, dm_disk(md));
+       blkdev_put(d->dm_dev.bdev);
+       d->dm_dev.bdev = NULL;
 }
 
 /*
  * If possible, this checks an area of a destination device is valid.
  */
-static int check_device_area(struct dm_dev *dd, sector_t start, sector_t len)
+static int check_device_area(struct dm_dev_internal *dd, sector_t start,
+                            sector_t len)
 {
-       sector_t dev_size = dd->bdev->bd_inode->i_size >> SECTOR_SHIFT;
+       sector_t dev_size = dd->dm_dev.bdev->bd_inode->i_size >> SECTOR_SHIFT;
 
        if (!dev_size)
                return 1;
@@ -392,16 +395,17 @@ static int check_device_area(struct dm_dev *dd, sector_t start, sector_t len)
  * careful to leave things as they were if we fail to reopen the
  * device.
  */
-static int upgrade_mode(struct dm_dev *dd, int new_mode, struct mapped_device *md)
+static int upgrade_mode(struct dm_dev_internal *dd, int new_mode,
+                       struct mapped_device *md)
 {
        int r;
-       struct dm_dev dd_copy;
-       dev_t dev = dd->bdev->bd_dev;
+       struct dm_dev_internal dd_copy;
+       dev_t dev = dd->dm_dev.bdev->bd_dev;
 
        dd_copy = *dd;
 
-       dd->mode |= new_mode;
-       dd->bdev = NULL;
+       dd->dm_dev.mode |= new_mode;
+       dd->dm_dev.bdev = NULL;
        r = open_dev(dd, dev, md);
        if (!r)
                close_dev(&dd_copy, md);
@@ -421,7 +425,7 @@ static int __table_get_device(struct dm_table *t, struct dm_target *ti,
 {
        int r;
        dev_t uninitialized_var(dev);
-       struct dm_dev *dd;
+       struct dm_dev_internal *dd;
        unsigned int major, minor;
 
        BUG_ON(!t);
@@ -443,20 +447,20 @@ static int __table_get_device(struct dm_table *t, struct dm_target *ti,
                if (!dd)
                        return -ENOMEM;
 
-               dd->mode = mode;
-               dd->bdev = NULL;
+               dd->dm_dev.mode = mode;
+               dd->dm_dev.bdev = NULL;
 
                if ((r = open_dev(dd, dev, t->md))) {
                        kfree(dd);
                        return r;
                }
 
-               format_dev_t(dd->name, dev);
+               format_dev_t(dd->dm_dev.name, dev);
 
                atomic_set(&dd->count, 0);
                list_add(&dd->list, &t->devices);
 
-       } else if (dd->mode != (mode | dd->mode)) {
+       } else if (dd->dm_dev.mode != (mode | dd->dm_dev.mode)) {
                r = upgrade_mode(dd, mode, t->md);
                if (r)
                        return r;
@@ -465,11 +469,11 @@ static int __table_get_device(struct dm_table *t, struct dm_target *ti,
 
        if (!check_device_area(dd, start, len)) {
                DMWARN("device %s too small for target", path);
-               dm_put_device(ti, dd);
+               dm_put_device(ti, &dd->dm_dev);
                return -EINVAL;
        }
 
-       *result = dd;
+       *result = &dd->dm_dev;
 
        return 0;
 }
@@ -478,6 +482,13 @@ void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev)
 {
        struct request_queue *q = bdev_get_queue(bdev);
        struct io_restrictions *rs = &ti->limits;
+       char b[BDEVNAME_SIZE];
+
+       if (unlikely(!q)) {
+               DMWARN("%s: Cannot set limits for nonexistent device %s",
+                      dm_device_name(ti->table->md), bdevname(bdev, b));
+               return;
+       }
 
        /*
         * Combine the device limits low.
@@ -540,8 +551,11 @@ int dm_get_device(struct dm_target *ti, const char *path, sector_t start,
 /*
  * Decrement a devices use count and remove it if necessary.
  */
-void dm_put_device(struct dm_target *ti, struct dm_dev *dd)
+void dm_put_device(struct dm_target *ti, struct dm_dev *d)
 {
+       struct dm_dev_internal *dd = container_of(d, struct dm_dev_internal,
+                                                 dm_dev);
+
        if (atomic_dec_and_test(&dd->count)) {
                close_dev(dd, ti->table->md);
                list_del(&dd->list);
@@ -937,13 +951,20 @@ int dm_table_resume_targets(struct dm_table *t)
 
 int dm_table_any_congested(struct dm_table *t, int bdi_bits)
 {
-       struct dm_dev *dd;
+       struct dm_dev_internal *dd;
        struct list_head *devices = dm_table_get_devices(t);
        int r = 0;
 
        list_for_each_entry(dd, devices, list) {
-               struct request_queue *q = bdev_get_queue(dd->bdev);
-               r |= bdi_congested(&q->backing_dev_info, bdi_bits);
+               struct request_queue *q = bdev_get_queue(dd->dm_dev.bdev);
+               char b[BDEVNAME_SIZE];
+
+               if (likely(q))
+                       r |= bdi_congested(&q->backing_dev_info, bdi_bits);
+               else
+                       DMWARN_LIMIT("%s: any_congested: nonexistent device %s",
+                                    dm_device_name(t->md),
+                                    bdevname(dd->dm_dev.bdev, b));
        }
 
        return r;
@@ -951,13 +972,19 @@ int dm_table_any_congested(struct dm_table *t, int bdi_bits)
 
 void dm_table_unplug_all(struct dm_table *t)
 {
-       struct dm_dev *dd;
+       struct dm_dev_internal *dd;
        struct list_head *devices = dm_table_get_devices(t);
 
        list_for_each_entry(dd, devices, list) {
-               struct request_queue *q = bdev_get_queue(dd->bdev);
-
-               blk_unplug(q);
+               struct request_queue *q = bdev_get_queue(dd->dm_dev.bdev);
+               char b[BDEVNAME_SIZE];
+
+               if (likely(q))
+                       blk_unplug(q);
+               else
+                       DMWARN_LIMIT("%s: Cannot unplug nonexistent device %s",
+                                    dm_device_name(t->md),
+                                    bdevname(dd->dm_dev.bdev, b));
        }
 }
 
index ace998ce59f6af2616da4a24eca66de8b59c69ba..327de03a5bdfed7f11b0904abb72f3eac65fc92d 100644 (file)
@@ -377,13 +377,14 @@ static void free_tio(struct mapped_device *md, struct dm_target_io *tio)
 static void start_io_acct(struct dm_io *io)
 {
        struct mapped_device *md = io->md;
+       int cpu;
 
        io->start_time = jiffies;
 
-       preempt_disable();
-       disk_round_stats(dm_disk(md));
-       preempt_enable();
-       dm_disk(md)->in_flight = atomic_inc_return(&md->pending);
+       cpu = part_stat_lock();
+       part_round_stats(cpu, &dm_disk(md)->part0);
+       part_stat_unlock();
+       dm_disk(md)->part0.in_flight = atomic_inc_return(&md->pending);
 }
 
 static int end_io_acct(struct dm_io *io)
@@ -391,15 +392,16 @@ static int end_io_acct(struct dm_io *io)
        struct mapped_device *md = io->md;
        struct bio *bio = io->bio;
        unsigned long duration = jiffies - io->start_time;
-       int pending;
+       int pending, cpu;
        int rw = bio_data_dir(bio);
 
-       preempt_disable();
-       disk_round_stats(dm_disk(md));
-       preempt_enable();
-       dm_disk(md)->in_flight = pending = atomic_dec_return(&md->pending);
+       cpu = part_stat_lock();
+       part_round_stats(cpu, &dm_disk(md)->part0);
+       part_stat_add(cpu, &dm_disk(md)->part0, ticks[rw], duration);
+       part_stat_unlock();
 
-       disk_stat_add(dm_disk(md), ticks[rw], duration);
+       dm_disk(md)->part0.in_flight = pending =
+               atomic_dec_return(&md->pending);
 
        return !pending;
 }
@@ -885,6 +887,7 @@ static int dm_request(struct request_queue *q, struct bio *bio)
        int r = -EIO;
        int rw = bio_data_dir(bio);
        struct mapped_device *md = q->queuedata;
+       int cpu;
 
        /*
         * There is no use in forwarding any barrier request since we can't
@@ -897,8 +900,10 @@ static int dm_request(struct request_queue *q, struct bio *bio)
 
        down_read(&md->io_lock);
 
-       disk_stat_inc(dm_disk(md), ios[rw]);
-       disk_stat_add(dm_disk(md), sectors[rw], bio_sectors(bio));
+       cpu = part_stat_lock();
+       part_stat_inc(cpu, &dm_disk(md)->part0, ios[rw]);
+       part_stat_add(cpu, &dm_disk(md)->part0, sectors[rw], bio_sectors(bio));
+       part_stat_unlock();
 
        /*
         * If we're suspended we have to queue
@@ -1146,7 +1151,7 @@ static void unlock_fs(struct mapped_device *md);
 
 static void free_dev(struct mapped_device *md)
 {
-       int minor = md->disk->first_minor;
+       int minor = MINOR(disk_devt(md->disk));
 
        if (md->suspended_bdev) {
                unlock_fs(md);
@@ -1182,7 +1187,7 @@ static void event_callback(void *context)
        list_splice_init(&md->uevent_list, &uevents);
        spin_unlock_irqrestore(&md->uevent_lock, flags);
 
-       dm_send_uevents(&uevents, &md->disk->dev.kobj);
+       dm_send_uevents(&uevents, &disk_to_dev(md->disk)->kobj);
 
        atomic_inc(&md->event_nr);
        wake_up(&md->eventq);
@@ -1267,7 +1272,7 @@ static struct mapped_device *dm_find_md(dev_t dev)
 
        md = idr_find(&_minor_idr, minor);
        if (md && (md == MINOR_ALLOCED ||
-                  (dm_disk(md)->first_minor != minor) ||
+                  (MINOR(disk_devt(dm_disk(md))) != minor) ||
                   test_bit(DMF_FREEING, &md->flags))) {
                md = NULL;
                goto out;
@@ -1318,7 +1323,8 @@ void dm_put(struct mapped_device *md)
 
        if (atomic_dec_and_lock(&md->holders, &_minor_lock)) {
                map = dm_get_table(md);
-               idr_replace(&_minor_idr, MINOR_ALLOCED, dm_disk(md)->first_minor);
+               idr_replace(&_minor_idr, MINOR_ALLOCED,
+                           MINOR(disk_devt(dm_disk(md))));
                set_bit(DMF_FREEING, &md->flags);
                spin_unlock(&_minor_lock);
                if (!dm_suspended(md)) {
@@ -1638,7 +1644,7 @@ out:
  *---------------------------------------------------------------*/
 void dm_kobject_uevent(struct mapped_device *md)
 {
-       kobject_uevent(&md->disk->dev.kobj, KOBJ_CHANGE);
+       kobject_uevent(&disk_to_dev(md->disk)->kobj, KOBJ_CHANGE);
 }
 
 uint32_t dm_next_uevent_seq(struct mapped_device *md)
index 1e59a0b0a78a0428a3c515280908062272e094d5..cd189da2b2fa1fbad7293f152f0744b7bdbb8c35 100644 (file)
 /*
  * List of devices that a metadevice uses and should open/close.
  */
-struct dm_dev {
+struct dm_dev_internal {
        struct list_head list;
-
        atomic_t count;
-       int mode;
-       struct block_device *bdev;
-       char name[16];
+       struct dm_dev dm_dev;
 };
 
 struct dm_table;
@@ -49,7 +46,6 @@ void dm_table_presuspend_targets(struct dm_table *t);
 void dm_table_postsuspend_targets(struct dm_table *t);
 int dm_table_resume_targets(struct dm_table *t);
 int dm_table_any_congested(struct dm_table *t, int bdi_bits);
-void dm_table_unplug_all(struct dm_table *t);
 
 /*
  * To check the return value from dm_table_find_target().
@@ -93,8 +89,6 @@ void dm_linear_exit(void);
 int dm_stripe_init(void);
 void dm_stripe_exit(void);
 
-void *dm_vcalloc(unsigned long nmemb, unsigned long elem_size);
-union map_info *dm_get_mapinfo(struct bio *bio);
 int dm_open_count(struct mapped_device *md);
 int dm_lock_for_deletion(struct mapped_device *md);
 
index b1eebf88c209a9abfb920eae921c1ec74459383c..b9cbee688fae9e4d28c9d62f58780d39254e0e3d 100644 (file)
@@ -318,14 +318,18 @@ static int linear_make_request (struct request_queue *q, struct bio *bio)
        mddev_t *mddev = q->queuedata;
        dev_info_t *tmp_dev;
        sector_t block;
+       int cpu;
 
        if (unlikely(bio_barrier(bio))) {
                bio_endio(bio, -EOPNOTSUPP);
                return 0;
        }
 
-       disk_stat_inc(mddev->gendisk, ios[rw]);
-       disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bio));
+       cpu = part_stat_lock();
+       part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]);
+       part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw],
+                     bio_sectors(bio));
+       part_stat_unlock();
 
        tmp_dev = which_dev(mddev, bio->bi_sector);
        block = bio->bi_sector >> 1;
@@ -349,7 +353,7 @@ static int linear_make_request (struct request_queue *q, struct bio *bio)
                 * split it.
                 */
                struct bio_pair *bp;
-               bp = bio_split(bio, bio_split_pool,
+               bp = bio_split(bio,
                               ((tmp_dev->offset + tmp_dev->size)<<1) - bio->bi_sector);
                if (linear_make_request(q, &bp->bio1))
                        generic_make_request(&bp->bio1);
index deeac4b44173d959b2fca6ca7f9abf57aa419f55..0a3a4bdcd4afd55ad52fd08ecc3d99713bcb9a87 100644 (file)
@@ -1464,10 +1464,7 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
        if ((err = kobject_add(&rdev->kobj, &mddev->kobj, "dev-%s", b)))
                goto fail;
 
-       if (rdev->bdev->bd_part)
-               ko = &rdev->bdev->bd_part->dev.kobj;
-       else
-               ko = &rdev->bdev->bd_disk->dev.kobj;
+       ko = &part_to_dev(rdev->bdev->bd_part)->kobj;
        if ((err = sysfs_create_link(&rdev->kobj, ko, "block"))) {
                kobject_del(&rdev->kobj);
                goto fail;
@@ -3470,8 +3467,8 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data)
        disk->queue = mddev->queue;
        add_disk(disk);
        mddev->gendisk = disk;
-       error = kobject_init_and_add(&mddev->kobj, &md_ktype, &disk->dev.kobj,
-                                    "%s", "md");
+       error = kobject_init_and_add(&mddev->kobj, &md_ktype,
+                                    &disk_to_dev(disk)->kobj, "%s", "md");
        mutex_unlock(&disks_mutex);
        if (error)
                printk(KERN_WARNING "md: cannot register %s/md - name in use\n",
@@ -3761,7 +3758,7 @@ static int do_md_run(mddev_t * mddev)
        sysfs_notify(&mddev->kobj, NULL, "array_state");
        sysfs_notify(&mddev->kobj, NULL, "sync_action");
        sysfs_notify(&mddev->kobj, NULL, "degraded");
-       kobject_uevent(&mddev->gendisk->dev.kobj, KOBJ_CHANGE);
+       kobject_uevent(&disk_to_dev(mddev->gendisk)->kobj, KOBJ_CHANGE);
        return 0;
 }
 
@@ -5549,8 +5546,8 @@ static int is_mddev_idle(mddev_t *mddev)
        rcu_read_lock();
        rdev_for_each_rcu(rdev, mddev) {
                struct gendisk *disk = rdev->bdev->bd_contains->bd_disk;
-               curr_events = disk_stat_read(disk, sectors[0]) + 
-                               disk_stat_read(disk, sectors[1]) - 
+               curr_events = part_stat_read(&disk->part0, sectors[0]) +
+                               part_stat_read(&disk->part0, sectors[1]) -
                                atomic_read(&disk->sync_io);
                /* sync IO will cause sync_io to increase before the disk_stats
                 * as sync_io is counted when a request starts, and
index c4779ccba1c39bf1ab3f7454706868245f95ea0e..8bb8794129b372c9fdd065d961437c54e774d110 100644 (file)
@@ -147,6 +147,7 @@ static int multipath_make_request (struct request_queue *q, struct bio * bio)
        struct multipath_bh * mp_bh;
        struct multipath_info *multipath;
        const int rw = bio_data_dir(bio);
+       int cpu;
 
        if (unlikely(bio_barrier(bio))) {
                bio_endio(bio, -EOPNOTSUPP);
@@ -158,8 +159,11 @@ static int multipath_make_request (struct request_queue *q, struct bio * bio)
        mp_bh->master_bio = bio;
        mp_bh->mddev = mddev;
 
-       disk_stat_inc(mddev->gendisk, ios[rw]);
-       disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bio));
+       cpu = part_stat_lock();
+       part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]);
+       part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw],
+                     bio_sectors(bio));
+       part_stat_unlock();
 
        mp_bh->path = multipath_map(conf);
        if (mp_bh->path < 0) {
index 18361063566113ffb3eddfd3d85f20fdbf6d5109..53508a8a981d70881eb130ef952033435e9b92f1 100644 (file)
@@ -399,14 +399,18 @@ static int raid0_make_request (struct request_queue *q, struct bio *bio)
        sector_t chunk;
        sector_t block, rsect;
        const int rw = bio_data_dir(bio);
+       int cpu;
 
        if (unlikely(bio_barrier(bio))) {
                bio_endio(bio, -EOPNOTSUPP);
                return 0;
        }
 
-       disk_stat_inc(mddev->gendisk, ios[rw]);
-       disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bio));
+       cpu = part_stat_lock();
+       part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]);
+       part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw],
+                     bio_sectors(bio));
+       part_stat_unlock();
 
        chunk_size = mddev->chunk_size >> 10;
        chunk_sects = mddev->chunk_size >> 9;
@@ -423,7 +427,7 @@ static int raid0_make_request (struct request_queue *q, struct bio *bio)
                /* This is a one page bio that upper layers
                 * refuse to split for us, so we need to split it.
                 */
-               bp = bio_split(bio, bio_split_pool, chunk_sects - (bio->bi_sector & (chunk_sects - 1)) );
+               bp = bio_split(bio, chunk_sects - (bio->bi_sector & (chunk_sects - 1)));
                if (raid0_make_request(q, &bp->bio1))
                        generic_make_request(&bp->bio1);
                if (raid0_make_request(q, &bp->bio2))
index 03a5ab705c20dcb482a98472d88b9e4d9d0d0a5d..b9764429d856ead58ec0ffd51bc06da21e0891fc 100644 (file)
@@ -779,7 +779,7 @@ static int make_request(struct request_queue *q, struct bio * bio)
        struct page **behind_pages = NULL;
        const int rw = bio_data_dir(bio);
        const int do_sync = bio_sync(bio);
-       int do_barriers;
+       int cpu, do_barriers;
        mdk_rdev_t *blocked_rdev;
 
        /*
@@ -804,8 +804,11 @@ static int make_request(struct request_queue *q, struct bio * bio)
 
        bitmap = mddev->bitmap;
 
-       disk_stat_inc(mddev->gendisk, ios[rw]);
-       disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bio));
+       cpu = part_stat_lock();
+       part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]);
+       part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw],
+                     bio_sectors(bio));
+       part_stat_unlock();
 
        /*
         * make_request() can abort the operation when READA is being
@@ -1302,9 +1305,6 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio)
                                        sbio->bi_size = r1_bio->sectors << 9;
                                        sbio->bi_idx = 0;
                                        sbio->bi_phys_segments = 0;
-                                       sbio->bi_hw_segments = 0;
-                                       sbio->bi_hw_front_size = 0;
-                                       sbio->bi_hw_back_size = 0;
                                        sbio->bi_flags &= ~(BIO_POOL_MASK - 1);
                                        sbio->bi_flags |= 1 << BIO_UPTODATE;
                                        sbio->bi_next = NULL;
@@ -1790,7 +1790,6 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
                bio->bi_vcnt = 0;
                bio->bi_idx = 0;
                bio->bi_phys_segments = 0;
-               bio->bi_hw_segments = 0;
                bio->bi_size = 0;
                bio->bi_end_io = NULL;
                bio->bi_private = NULL;
index e34cd0e6247385f5827d7232ae4257c664f47c7b..8bdc9bfc288703aafbc8b20925f3d9b8e337fd54 100644 (file)
@@ -789,6 +789,7 @@ static int make_request(struct request_queue *q, struct bio * bio)
        mirror_info_t *mirror;
        r10bio_t *r10_bio;
        struct bio *read_bio;
+       int cpu;
        int i;
        int chunk_sects = conf->chunk_mask + 1;
        const int rw = bio_data_dir(bio);
@@ -816,7 +817,7 @@ static int make_request(struct request_queue *q, struct bio * bio)
                /* This is a one page bio that upper layers
                 * refuse to split for us, so we need to split it.
                 */
-               bp = bio_split(bio, bio_split_pool,
+               bp = bio_split(bio,
                               chunk_sects - (bio->bi_sector & (chunk_sects - 1)) );
                if (make_request(q, &bp->bio1))
                        generic_make_request(&bp->bio1);
@@ -843,8 +844,11 @@ static int make_request(struct request_queue *q, struct bio * bio)
         */
        wait_barrier(conf);
 
-       disk_stat_inc(mddev->gendisk, ios[rw]);
-       disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bio));
+       cpu = part_stat_lock();
+       part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]);
+       part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw],
+                     bio_sectors(bio));
+       part_stat_unlock();
 
        r10_bio = mempool_alloc(conf->r10bio_pool, GFP_NOIO);
 
@@ -1345,9 +1349,6 @@ static void sync_request_write(mddev_t *mddev, r10bio_t *r10_bio)
                tbio->bi_size = r10_bio->sectors << 9;
                tbio->bi_idx = 0;
                tbio->bi_phys_segments = 0;
-               tbio->bi_hw_segments = 0;
-               tbio->bi_hw_front_size = 0;
-               tbio->bi_hw_back_size = 0;
                tbio->bi_flags &= ~(BIO_POOL_MASK - 1);
                tbio->bi_flags |= 1 << BIO_UPTODATE;
                tbio->bi_next = NULL;
@@ -1947,7 +1948,6 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
                bio->bi_vcnt = 0;
                bio->bi_idx = 0;
                bio->bi_phys_segments = 0;
-               bio->bi_hw_segments = 0;
                bio->bi_size = 0;
        }
 
index 224de022e7c5d6574cf46747947b3c9e326c8632..ae16794bef209eeeae6cae8f074c6778674dd068 100644 (file)
 const char raid6_empty_zero_page[PAGE_SIZE] __attribute__((aligned(256)));
 #endif
 
+/*
+ * We maintain a biased count of active stripes in the bottom 16 bits of
+ * bi_phys_segments, and a count of processed stripes in the upper 16 bits
+ */
+static inline int raid5_bi_phys_segments(struct bio *bio)
+{
+       return bio->bi_phys_segments & 0xffff;
+}
+
+static inline int raid5_bi_hw_segments(struct bio *bio)
+{
+       return (bio->bi_phys_segments >> 16) & 0xffff;
+}
+
+static inline int raid5_dec_bi_phys_segments(struct bio *bio)
+{
+       --bio->bi_phys_segments;
+       return raid5_bi_phys_segments(bio);
+}
+
+static inline int raid5_dec_bi_hw_segments(struct bio *bio)
+{
+       unsigned short val = raid5_bi_hw_segments(bio);
+
+       --val;
+       bio->bi_phys_segments = (val << 16) | raid5_bi_phys_segments(bio);
+       return val;
+}
+
+static inline void raid5_set_bi_hw_segments(struct bio *bio, unsigned int cnt)
+{
+       bio->bi_phys_segments = raid5_bi_phys_segments(bio) || (cnt << 16);
+}
+
 static inline int raid6_next_disk(int disk, int raid_disks)
 {
        disk++;
@@ -507,7 +541,7 @@ static void ops_complete_biofill(void *stripe_head_ref)
                        while (rbi && rbi->bi_sector <
                                dev->sector + STRIPE_SECTORS) {
                                rbi2 = r5_next_bio(rbi, dev->sector);
-                               if (--rbi->bi_phys_segments == 0) {
+                               if (!raid5_dec_bi_phys_segments(rbi)) {
                                        rbi->bi_next = return_bi;
                                        return_bi = rbi;
                                }
@@ -1725,7 +1759,7 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, in
        if (*bip)
                bi->bi_next = *bip;
        *bip = bi;
-       bi->bi_phys_segments ++;
+       bi->bi_phys_segments++;
        spin_unlock_irq(&conf->device_lock);
        spin_unlock(&sh->lock);
 
@@ -1819,7 +1853,7 @@ handle_failed_stripe(raid5_conf_t *conf, struct stripe_head *sh,
                        sh->dev[i].sector + STRIPE_SECTORS) {
                        struct bio *nextbi = r5_next_bio(bi, sh->dev[i].sector);
                        clear_bit(BIO_UPTODATE, &bi->bi_flags);
-                       if (--bi->bi_phys_segments == 0) {
+                       if (!raid5_dec_bi_phys_segments(bi)) {
                                md_write_end(conf->mddev);
                                bi->bi_next = *return_bi;
                                *return_bi = bi;
@@ -1834,7 +1868,7 @@ handle_failed_stripe(raid5_conf_t *conf, struct stripe_head *sh,
                       sh->dev[i].sector + STRIPE_SECTORS) {
                        struct bio *bi2 = r5_next_bio(bi, sh->dev[i].sector);
                        clear_bit(BIO_UPTODATE, &bi->bi_flags);
-                       if (--bi->bi_phys_segments == 0) {
+                       if (!raid5_dec_bi_phys_segments(bi)) {
                                md_write_end(conf->mddev);
                                bi->bi_next = *return_bi;
                                *return_bi = bi;
@@ -1858,7 +1892,7 @@ handle_failed_stripe(raid5_conf_t *conf, struct stripe_head *sh,
                                struct bio *nextbi =
                                        r5_next_bio(bi, sh->dev[i].sector);
                                clear_bit(BIO_UPTODATE, &bi->bi_flags);
-                               if (--bi->bi_phys_segments == 0) {
+                               if (!raid5_dec_bi_phys_segments(bi)) {
                                        bi->bi_next = *return_bi;
                                        *return_bi = bi;
                                }
@@ -2033,7 +2067,7 @@ static void handle_stripe_clean_event(raid5_conf_t *conf,
                                while (wbi && wbi->bi_sector <
                                        dev->sector + STRIPE_SECTORS) {
                                        wbi2 = r5_next_bio(wbi, dev->sector);
-                                       if (--wbi->bi_phys_segments == 0) {
+                                       if (!raid5_dec_bi_phys_segments(wbi)) {
                                                md_write_end(conf->mddev);
                                                wbi->bi_next = *return_bi;
                                                *return_bi = wbi;
@@ -2814,7 +2848,7 @@ static bool handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
                                copy_data(0, rbi, dev->page, dev->sector);
                                rbi2 = r5_next_bio(rbi, dev->sector);
                                spin_lock_irq(&conf->device_lock);
-                               if (--rbi->bi_phys_segments == 0) {
+                               if (!raid5_dec_bi_phys_segments(rbi)) {
                                        rbi->bi_next = return_bi;
                                        return_bi = rbi;
                                }
@@ -3155,8 +3189,11 @@ static struct bio *remove_bio_from_retry(raid5_conf_t *conf)
        if(bi) {
                conf->retry_read_aligned_list = bi->bi_next;
                bi->bi_next = NULL;
+               /*
+                * this sets the active strip count to 1 and the processed
+                * strip count to zero (upper 8 bits)
+                */
                bi->bi_phys_segments = 1; /* biased count of active stripes */
-               bi->bi_hw_segments = 0; /* count of processed stripes */
        }
 
        return bi;
@@ -3206,8 +3243,7 @@ static int bio_fits_rdev(struct bio *bi)
        if ((bi->bi_size>>9) > q->max_sectors)
                return 0;
        blk_recount_segments(q, bi);
-       if (bi->bi_phys_segments > q->max_phys_segments ||
-           bi->bi_hw_segments > q->max_hw_segments)
+       if (bi->bi_phys_segments > q->max_phys_segments)
                return 0;
 
        if (q->merge_bvec_fn)
@@ -3351,7 +3387,7 @@ static int make_request(struct request_queue *q, struct bio * bi)
        sector_t logical_sector, last_sector;
        struct stripe_head *sh;
        const int rw = bio_data_dir(bi);
-       int remaining;
+       int cpu, remaining;
 
        if (unlikely(bio_barrier(bi))) {
                bio_endio(bi, -EOPNOTSUPP);
@@ -3360,8 +3396,11 @@ static int make_request(struct request_queue *q, struct bio * bi)
 
        md_write_start(mddev, bi);
 
-       disk_stat_inc(mddev->gendisk, ios[rw]);
-       disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bi));
+       cpu = part_stat_lock();
+       part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]);
+       part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw],
+                     bio_sectors(bi));
+       part_stat_unlock();
 
        if (rw == READ &&
             mddev->reshape_position == MaxSector &&
@@ -3468,7 +3507,7 @@ static int make_request(struct request_queue *q, struct bio * bi)
                        
        }
        spin_lock_irq(&conf->device_lock);
-       remaining = --bi->bi_phys_segments;
+       remaining = raid5_dec_bi_phys_segments(bi);
        spin_unlock_irq(&conf->device_lock);
        if (remaining == 0) {
 
@@ -3752,7 +3791,7 @@ static int  retry_aligned_read(raid5_conf_t *conf, struct bio *raid_bio)
                     sector += STRIPE_SECTORS,
                     scnt++) {
 
-               if (scnt < raid_bio->bi_hw_segments)
+               if (scnt < raid5_bi_hw_segments(raid_bio))
                        /* already done this stripe */
                        continue;
 
@@ -3760,7 +3799,7 @@ static int  retry_aligned_read(raid5_conf_t *conf, struct bio *raid_bio)
 
                if (!sh) {
                        /* failed to get a stripe - must wait */
-                       raid_bio->bi_hw_segments = scnt;
+                       raid5_set_bi_hw_segments(raid_bio, scnt);
                        conf->retry_read_aligned = raid_bio;
                        return handled;
                }
@@ -3768,7 +3807,7 @@ static int  retry_aligned_read(raid5_conf_t *conf, struct bio *raid_bio)
                set_bit(R5_ReadError, &sh->dev[dd_idx].flags);
                if (!add_stripe_bio(sh, raid_bio, dd_idx, 0)) {
                        release_stripe(sh);
-                       raid_bio->bi_hw_segments = scnt;
+                       raid5_set_bi_hw_segments(raid_bio, scnt);
                        conf->retry_read_aligned = raid_bio;
                        return handled;
                }
@@ -3778,7 +3817,7 @@ static int  retry_aligned_read(raid5_conf_t *conf, struct bio *raid_bio)
                handled++;
        }
        spin_lock_irq(&conf->device_lock);
-       remaining = --raid_bio->bi_phys_segments;
+       remaining = raid5_dec_bi_phys_segments(raid_bio);
        spin_unlock_irq(&conf->device_lock);
        if (remaining == 0)
                bio_endio(raid_bio, 0);
index d2d2318dafa4af7fd8ab885528f693bd886e5e54..6e291bf8237adaa0d7c5ea84f8ffda8e9ee440e3 100644 (file)
@@ -197,7 +197,7 @@ static int mspro_block_bd_open(struct inode *inode, struct file *filp)
 static int mspro_block_disk_release(struct gendisk *disk)
 {
        struct mspro_block_data *msb = disk->private_data;
-       int disk_id = disk->first_minor >> MSPRO_BLOCK_PART_SHIFT;
+       int disk_id = MINOR(disk_devt(disk)) >> MSPRO_BLOCK_PART_SHIFT;
 
        mutex_lock(&mspro_block_disk_lock);
 
@@ -828,7 +828,7 @@ static void mspro_block_submit_req(struct request_queue *q)
 
        if (msb->eject) {
                while ((req = elv_next_request(q)) != NULL)
-                       end_queued_request(req, -ENODEV);
+                       __blk_end_request(req, -ENODEV, blk_rq_bytes(req));
 
                return;
        }
index facdb9893c84c322dbb65f47e2a7bf8de3c69685..1ee8501e90f11eb7e350355712625120dd2a5aeb 100644 (file)
@@ -450,12 +450,14 @@ static int eeepc_get_fan_pwm(void)
        int value = 0;
 
        read_acpi_int(NULL, EEEPC_EC_FAN_PWM, &value);
+       value = value * 255 / 100;
        return (value);
 }
 
 static void eeepc_set_fan_pwm(int value)
 {
-       value = SENSORS_LIMIT(value, 0, 100);
+       value = SENSORS_LIMIT(value, 0, 255);
+       value = value * 100 / 255;
        ec_write(EEEPC_EC_SC02, value);
 }
 
@@ -520,15 +522,23 @@ static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
        static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
 
 EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL);
-EEEPC_CREATE_SENSOR_ATTR(fan1_pwm, S_IRUGO | S_IWUSR,
+EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR,
                         eeepc_get_fan_pwm, eeepc_set_fan_pwm);
 EEEPC_CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
                         eeepc_get_fan_ctrl, eeepc_set_fan_ctrl);
 
+static ssize_t
+show_name(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       return sprintf(buf, "eeepc\n");
+}
+static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
+
 static struct attribute *hwmon_attributes[] = {
-       &sensor_dev_attr_fan1_pwm.dev_attr.attr,
+       &sensor_dev_attr_pwm1.dev_attr.attr,
        &sensor_dev_attr_fan1_input.dev_attr.attr,
        &sensor_dev_attr_pwm1_enable.dev_attr.attr,
+       &sensor_dev_attr_name.dev_attr.attr,
        NULL
 };
 
index ebc8b9d77613132f290b7372196ab50bfe416144..efacee0404a09c703b7f259fb0cb37401021b518 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/blkdev.h>
 #include <linux/mutex.h>
 #include <linux/scatterlist.h>
+#include <linux/string_helpers.h>
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
@@ -83,7 +84,7 @@ static void mmc_blk_put(struct mmc_blk_data *md)
        mutex_lock(&open_lock);
        md->usage--;
        if (md->usage == 0) {
-               int devidx = md->disk->first_minor >> MMC_SHIFT;
+               int devidx = MINOR(disk_devt(md->disk)) >> MMC_SHIFT;
                __clear_bit(devidx, dev_use);
 
                put_disk(md->disk);
@@ -532,6 +533,8 @@ static int mmc_blk_probe(struct mmc_card *card)
        struct mmc_blk_data *md;
        int err;
 
+       char cap_str[10];
+
        /*
         * Check that the card supports the command class(es) we need.
         */
@@ -546,10 +549,11 @@ static int mmc_blk_probe(struct mmc_card *card)
        if (err)
                goto out;
 
-       printk(KERN_INFO "%s: %s %s %lluKiB %s\n",
+       string_get_size(get_capacity(md->disk) << 9, STRING_UNITS_2,
+                       cap_str, sizeof(cap_str));
+       printk(KERN_INFO "%s: %s %s %s %s\n",
                md->disk->disk_name, mmc_card_id(card), mmc_card_name(card),
-               (unsigned long long)(get_capacity(md->disk) >> 1),
-               md->read_only ? "(ro)" : "");
+               cap_str, md->read_only ? "(ro)" : "");
 
        mmc_set_drvdata(card, md);
        add_disk(md->disk);
index f34f20c7891162f6d5fb7c101d3cac9c55da2e82..9bf581c4f740e775f590842004fc52568ce8fc9e 100644 (file)
@@ -1005,6 +1005,29 @@ static int ftl_writesect(struct mtd_blktrans_dev *dev,
        return ftl_write((void *)dev, buf, block, 1);
 }
 
+static int ftl_discardsect(struct mtd_blktrans_dev *dev,
+                          unsigned long sector, unsigned nr_sects)
+{
+       partition_t *part = (void *)dev;
+       uint32_t bsize = 1 << part->header.EraseUnitSize;
+
+       DEBUG(1, "FTL erase sector %ld for %d sectors\n",
+             sector, nr_sects);
+
+       while (nr_sects) {
+               uint32_t old_addr = part->VirtualBlockMap[sector];
+               if (old_addr != 0xffffffff) {
+                       part->VirtualBlockMap[sector] = 0xffffffff;
+                       part->EUNInfo[old_addr/bsize].Deleted++;
+                       if (set_bam_entry(part, old_addr, 0))
+                               return -EIO;
+               }
+               nr_sects--;
+               sector++;
+       }
+
+       return 0;
+}
 /*====================================================================*/
 
 static void ftl_freepart(partition_t *part)
@@ -1069,6 +1092,7 @@ static struct mtd_blktrans_ops ftl_tr = {
        .blksize        = SECTOR_SIZE,
        .readsect       = ftl_readsect,
        .writesect      = ftl_writesect,
+       .discard        = ftl_discardsect,
        .getgeo         = ftl_getgeo,
        .add_mtd        = ftl_add_mtd,
        .remove_dev     = ftl_remove_dev,
index 9ff007c4962c9f3c58868385729a915ba6b28222..681d5aca2af436630fda1d5124d8a3d6a1e70ce4 100644 (file)
@@ -32,6 +32,14 @@ struct mtd_blkcore_priv {
        spinlock_t queue_lock;
 };
 
+static int blktrans_discard_request(struct request_queue *q,
+                                   struct request *req)
+{
+       req->cmd_type = REQ_TYPE_LINUX_BLOCK;
+       req->cmd[0] = REQ_LB_OP_DISCARD;
+       return 0;
+}
+
 static int do_blktrans_request(struct mtd_blktrans_ops *tr,
                               struct mtd_blktrans_dev *dev,
                               struct request *req)
@@ -44,6 +52,10 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
 
        buf = req->buffer;
 
+       if (req->cmd_type == REQ_TYPE_LINUX_BLOCK &&
+           req->cmd[0] == REQ_LB_OP_DISCARD)
+               return !tr->discard(dev, block, nsect);
+
        if (!blk_fs_request(req))
                return 0;
 
@@ -367,6 +379,10 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
 
        tr->blkcore_priv->rq->queuedata = tr;
        blk_queue_hardsect_size(tr->blkcore_priv->rq, tr->blksize);
+       if (tr->discard)
+               blk_queue_set_discard(tr->blkcore_priv->rq,
+                                     blktrans_discard_request);
+
        tr->blkshift = ffs(tr->blksize) - 1;
 
        tr->blkcore_priv->thread = kthread_run(mtd_blktrans_thread, tr,
index 26f5abc9c3f7d604d926ec32e77570d4fd1a8363..e83f34f1b5bada1207cb4bf8e77badaac623e2e1 100644 (file)
@@ -2,12 +2,15 @@
 # Makefile for the Linux Plug-and-Play Support.
 #
 
-obj-y          := core.o card.o driver.o resource.o manager.o support.o interface.o quirks.o system.o
+obj-y          := core.o card.o driver.o resource.o manager.o support.o interface.o quirks.o
 
 obj-$(CONFIG_PNPACPI)          += pnpacpi/
 obj-$(CONFIG_PNPBIOS)          += pnpbios/
 obj-$(CONFIG_ISAPNP)           += isapnp/
 
+# pnp_system_init goes after pnpacpi/pnpbios init
+obj-y                          += system.o
+
 ifeq ($(CONFIG_PNP_DEBUG),y)
 EXTRA_CFLAGS += -DDEBUG
 endif
index c1b9ea34977b395c400fcd522ecd41f06fadbd21..53561d72b4eef0795e41054476060093d1053dbe 100644 (file)
@@ -268,7 +268,7 @@ static int __init pnpacpi_init(void)
        return 0;
 }
 
-subsys_initcall(pnpacpi_init);
+fs_initcall(pnpacpi_init);
 
 static int __init pnpacpi_setup(char *str)
 {
index 19a4be1a9a31afd73567724ccdf3b56a03445bc7..662dfcddedc62fce03362f72cd79c421f6542a37 100644 (file)
@@ -571,7 +571,7 @@ static int __init pnpbios_init(void)
        return 0;
 }
 
-subsys_initcall(pnpbios_init);
+fs_initcall(pnpbios_init);
 
 static int __init pnpbios_thread_init(void)
 {
index 03c0e40a92ff9fafc20694ee0127822d03a4db4f..e3b5c4d3036e693ec0f5b7601bbf681c06f9aaea 100644 (file)
@@ -76,7 +76,8 @@ dasd_devices_show(struct seq_file *m, void *v)
        /* Print kdev. */
        if (block->gdp)
                seq_printf(m, " at (%3d:%6d)",
-                          block->gdp->major, block->gdp->first_minor);
+                          MAJOR(disk_devt(block->gdp)),
+                          MINOR(disk_devt(block->gdp)));
        else
                seq_printf(m, "  at (???:??????)");
        /* Print device name. */
index 711b3004b3e6a6419540bad5fa067dcc817b6d99..9481e4a3f76ee39cdf2aa9a0f543a831792b6cbd 100644 (file)
@@ -114,7 +114,7 @@ dcssblk_assign_free_minor(struct dcssblk_dev_info *dev_info)
                found = 0;
                // test if minor available
                list_for_each_entry(entry, &dcssblk_devices, lh)
-                       if (minor == entry->gd->first_minor)
+                       if (minor == MINOR(disk_devt(entry->gd)))
                                found++;
                if (!found) break; // got unused minor
        }
@@ -397,7 +397,7 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
                goto unload_seg;
        }
        sprintf(dev_info->gd->disk_name, "dcssblk%d",
-               dev_info->gd->first_minor);
+               MINOR(disk_devt(dev_info->gd)));
        list_add_tail(&dev_info->lh, &dcssblk_devices);
 
        if (!try_module_get(THIS_MODULE)) {
index 90abfd06ed55768b363d1c05a58c8837b1af9d7c..24255e42dc30bbb4aa6283c31ac1ea170a62b661 100644 (file)
@@ -88,11 +88,13 @@ static int __init zfcp_device_setup(char *devstr)
        strncpy(zfcp_data.init_busid, token, BUS_ID_SIZE);
 
        token = strsep(&str, ",");
-       if (!token || strict_strtoull(token, 0, &zfcp_data.init_wwpn))
+       if (!token || strict_strtoull(token, 0,
+                               (unsigned long long *) &zfcp_data.init_wwpn))
                goto err_out;
 
        token = strsep(&str, ",");
-       if (!token || strict_strtoull(token, 0, &zfcp_data.init_fcp_lun))
+       if (!token || strict_strtoull(token, 0,
+                               (unsigned long long *) &zfcp_data.init_fcp_lun))
                goto err_out;
 
        kfree(str);
@@ -100,24 +102,10 @@ static int __init zfcp_device_setup(char *devstr)
 
  err_out:
        kfree(str);
-       pr_err("zfcp: Parse error for device parameter string %s, "
-              "device not attached.\n", devstr);
+       pr_err("zfcp: %s is not a valid SCSI device\n", devstr);
        return 0;
 }
 
-static struct zfcp_adapter *zfcp_get_adapter_by_busid(char *bus_id)
-{
-       struct zfcp_adapter *adapter;
-
-       list_for_each_entry(adapter, &zfcp_data.adapter_list_head, list)
-               if ((strncmp(bus_id, adapter->ccw_device->dev.bus_id,
-                            BUS_ID_SIZE) == 0) &&
-                   !(atomic_read(&adapter->status) &
-                     ZFCP_STATUS_COMMON_REMOVE))
-                   return adapter;
-       return NULL;
-}
-
 static void __init zfcp_init_device_configure(void)
 {
        struct zfcp_adapter *adapter;
@@ -141,7 +129,12 @@ static void __init zfcp_init_device_configure(void)
                goto out_unit;
        up(&zfcp_data.config_sema);
        ccw_device_set_online(adapter->ccw_device);
+
        zfcp_erp_wait(adapter);
+       wait_event(adapter->erp_done_wqh,
+                  !(atomic_read(&unit->status) &
+                               ZFCP_STATUS_UNIT_SCSI_WORK_PENDING));
+
        down(&zfcp_data.config_sema);
        zfcp_unit_put(unit);
 out_unit:
@@ -180,9 +173,9 @@ static int __init zfcp_module_init(void)
        if (!zfcp_data.gid_pn_cache)
                goto out_gid_cache;
 
-       INIT_LIST_HEAD(&zfcp_data.adapter_list_head);
-       INIT_LIST_HEAD(&zfcp_data.adapter_remove_lh);
+       zfcp_data.work_queue = create_singlethread_workqueue("zfcp_wq");
 
+       INIT_LIST_HEAD(&zfcp_data.adapter_list_head);
        sema_init(&zfcp_data.config_sema, 1);
        rwlock_init(&zfcp_data.config_lock);
 
@@ -193,13 +186,14 @@ static int __init zfcp_module_init(void)
 
        retval = misc_register(&zfcp_cfdc_misc);
        if (retval) {
-               pr_err("zfcp: registration of misc device zfcp_cfdc failed\n");
+               pr_err("zfcp: Registering the misc device zfcp_cfdc failed\n");
                goto out_misc;
        }
 
        retval = zfcp_ccw_register();
        if (retval) {
-               pr_err("zfcp: Registration with common I/O layer failed.\n");
+               pr_err("zfcp: The zfcp device driver could not register with "
+                      "the common I/O layer\n");
                goto out_ccw_register;
        }
 
@@ -231,8 +225,7 @@ module_init(zfcp_module_init);
  *
  * Returns: pointer to zfcp_unit or NULL
  */
-struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *port,
-                                      fcp_lun_t fcp_lun)
+struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *port, u64 fcp_lun)
 {
        struct zfcp_unit *unit;
 
@@ -251,7 +244,7 @@ struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *port,
  * Returns: pointer to zfcp_port or NULL
  */
 struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *adapter,
-                                       wwn_t wwpn)
+                                       u64 wwpn)
 {
        struct zfcp_port *port;
 
@@ -276,7 +269,7 @@ static void zfcp_sysfs_unit_release(struct device *dev)
  *
  * Sets up some unit internal structures and creates sysfs entry.
  */
-struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun)
+struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
 {
        struct zfcp_unit *unit;
 
@@ -290,7 +283,8 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun)
        unit->port = port;
        unit->fcp_lun = fcp_lun;
 
-       snprintf(unit->sysfs_device.bus_id, BUS_ID_SIZE, "0x%016llx", fcp_lun);
+       snprintf(unit->sysfs_device.bus_id, BUS_ID_SIZE, "0x%016llx",
+                (unsigned long long) fcp_lun);
        unit->sysfs_device.parent = &port->sysfs_device;
        unit->sysfs_device.release = zfcp_sysfs_unit_release;
        dev_set_drvdata(&unit->sysfs_device, unit);
@@ -323,7 +317,6 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun)
        }
 
        zfcp_unit_get(unit);
-       unit->scsi_lun = scsilun_to_int((struct scsi_lun *)&unit->fcp_lun);
 
        write_lock_irq(&zfcp_data.config_lock);
        list_add_tail(&unit->list, &port->unit_list_head);
@@ -332,7 +325,6 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun)
 
        write_unlock_irq(&zfcp_data.config_lock);
 
-       port->units++;
        zfcp_port_get(port);
 
        return unit;
@@ -351,11 +343,10 @@ err_out_free:
  */
 void zfcp_unit_dequeue(struct zfcp_unit *unit)
 {
-       zfcp_unit_wait(unit);
+       wait_event(unit->remove_wq, atomic_read(&unit->refcount) == 0);
        write_lock_irq(&zfcp_data.config_lock);
        list_del(&unit->list);
        write_unlock_irq(&zfcp_data.config_lock);
-       unit->port->units--;
        zfcp_port_put(unit->port);
        sysfs_remove_group(&unit->sysfs_device.kobj, &zfcp_sysfs_unit_attrs);
        device_unregister(&unit->sysfs_device);
@@ -416,11 +407,6 @@ static void zfcp_free_low_mem_buffers(struct zfcp_adapter *adapter)
                mempool_destroy(adapter->pool.data_gid_pn);
 }
 
-static void zfcp_dummy_release(struct device *dev)
-{
-       return;
-}
-
 /**
  * zfcp_status_read_refill - refill the long running status_read_requests
  * @adapter: ptr to struct zfcp_adapter for which the buffers should be refilled
@@ -450,19 +436,6 @@ static void _zfcp_status_read_scheduler(struct work_struct *work)
                                             stat_work));
 }
 
-static int zfcp_nameserver_enqueue(struct zfcp_adapter *adapter)
-{
-       struct zfcp_port *port;
-
-       port = zfcp_port_enqueue(adapter, 0, ZFCP_STATUS_PORT_WKA,
-                                ZFCP_DID_DIRECTORY_SERVICE);
-       if (IS_ERR(port))
-               return PTR_ERR(port);
-       zfcp_port_put(port);
-
-       return 0;
-}
-
 /**
  * zfcp_adapter_enqueue - enqueue a new adapter to the list
  * @ccw_device: pointer to the struct cc_device
@@ -508,7 +481,6 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
        init_waitqueue_head(&adapter->erp_done_wqh);
 
        INIT_LIST_HEAD(&adapter->port_list_head);
-       INIT_LIST_HEAD(&adapter->port_remove_lh);
        INIT_LIST_HEAD(&adapter->erp_ready_head);
        INIT_LIST_HEAD(&adapter->erp_running_head);
 
@@ -518,7 +490,7 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
        spin_lock_init(&adapter->san_dbf_lock);
        spin_lock_init(&adapter->scsi_dbf_lock);
        spin_lock_init(&adapter->rec_dbf_lock);
-       spin_lock_init(&adapter->req_q.lock);
+       spin_lock_init(&adapter->req_q_lock);
 
        rwlock_init(&adapter->erp_lock);
        rwlock_init(&adapter->abort_lock);
@@ -537,28 +509,15 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
                               &zfcp_sysfs_adapter_attrs))
                goto sysfs_failed;
 
-       adapter->generic_services.parent = &adapter->ccw_device->dev;
-       adapter->generic_services.release = zfcp_dummy_release;
-       snprintf(adapter->generic_services.bus_id, BUS_ID_SIZE,
-                "generic_services");
-
-       if (device_register(&adapter->generic_services))
-               goto generic_services_failed;
-
        write_lock_irq(&zfcp_data.config_lock);
        atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
        list_add_tail(&adapter->list, &zfcp_data.adapter_list_head);
        write_unlock_irq(&zfcp_data.config_lock);
 
-       zfcp_data.adapters++;
-
-       zfcp_nameserver_enqueue(adapter);
+       zfcp_fc_nameserver_init(adapter);
 
        return 0;
 
-generic_services_failed:
-       sysfs_remove_group(&ccw_device->dev.kobj,
-                          &zfcp_sysfs_adapter_attrs);
 sysfs_failed:
        zfcp_adapter_debug_unregister(adapter);
 debug_register_failed:
@@ -585,7 +544,6 @@ void zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
        cancel_work_sync(&adapter->scan_work);
        cancel_work_sync(&adapter->stat_work);
        zfcp_adapter_scsi_unregister(adapter);
-       device_unregister(&adapter->generic_services);
        sysfs_remove_group(&adapter->ccw_device->dev.kobj,
                           &zfcp_sysfs_adapter_attrs);
        dev_set_drvdata(&adapter->ccw_device->dev, NULL);
@@ -603,9 +561,6 @@ void zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
        list_del(&adapter->list);
        write_unlock_irq(&zfcp_data.config_lock);
 
-       /* decrease number of adapters in list */
-       zfcp_data.adapters--;
-
        zfcp_qdio_free(adapter);
 
        zfcp_free_low_mem_buffers(adapter);
@@ -633,21 +588,19 @@ static void zfcp_sysfs_port_release(struct device *dev)
  * d_id is used to enqueue ports with a well known address like the Directory
  * Service for nameserver lookup.
  */
-struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn,
+struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
                                     u32 status, u32 d_id)
 {
        struct zfcp_port *port;
        int retval;
-       char *bus_id;
 
        port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL);
        if (!port)
                return ERR_PTR(-ENOMEM);
 
        init_waitqueue_head(&port->remove_wq);
-
        INIT_LIST_HEAD(&port->unit_list_head);
-       INIT_LIST_HEAD(&port->unit_remove_lh);
+       INIT_WORK(&port->gid_pn_work, zfcp_erp_port_strategy_open_lookup);
 
        port->adapter = adapter;
        port->d_id = d_id;
@@ -657,34 +610,9 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn,
        atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status);
        atomic_set(&port->refcount, 0);
 
-       if (status & ZFCP_STATUS_PORT_WKA) {
-               switch (d_id) {
-               case ZFCP_DID_DIRECTORY_SERVICE:
-                       bus_id = "directory";
-                       break;
-               case ZFCP_DID_MANAGEMENT_SERVICE:
-                       bus_id = "management";
-                       break;
-               case ZFCP_DID_KEY_DISTRIBUTION_SERVICE:
-                       bus_id = "key_distribution";
-                       break;
-               case ZFCP_DID_ALIAS_SERVICE:
-                       bus_id = "alias";
-                       break;
-               case ZFCP_DID_TIME_SERVICE:
-                       bus_id = "time";
-                       break;
-               default:
-                       kfree(port);
-                       return ERR_PTR(-EINVAL);
-               }
-               snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE, "%s", bus_id);
-               port->sysfs_device.parent = &adapter->generic_services;
-       } else {
-               snprintf(port->sysfs_device.bus_id,
-                        BUS_ID_SIZE, "0x%016llx", wwpn);
-               port->sysfs_device.parent = &adapter->ccw_device->dev;
-       }
+       snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE, "0x%016llx",
+                (unsigned long long) wwpn);
+       port->sysfs_device.parent = &adapter->ccw_device->dev;
 
        port->sysfs_device.release = zfcp_sysfs_port_release;
        dev_set_drvdata(&port->sysfs_device, port);
@@ -700,12 +628,8 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn,
        if (device_register(&port->sysfs_device))
                goto err_out_free;
 
-       if (status & ZFCP_STATUS_PORT_WKA)
-               retval = sysfs_create_group(&port->sysfs_device.kobj,
-                                           &zfcp_sysfs_ns_port_attrs);
-       else
-               retval = sysfs_create_group(&port->sysfs_device.kobj,
-                                           &zfcp_sysfs_port_attrs);
+       retval = sysfs_create_group(&port->sysfs_device.kobj,
+                                   &zfcp_sysfs_port_attrs);
 
        if (retval) {
                device_unregister(&port->sysfs_device);
@@ -718,10 +642,6 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn,
        list_add_tail(&port->list, &adapter->port_list_head);
        atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
        atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &port->status);
-       if (d_id == ZFCP_DID_DIRECTORY_SERVICE)
-               if (!adapter->nameserver_port)
-                       adapter->nameserver_port = port;
-       adapter->ports++;
 
        write_unlock_irq(&zfcp_data.config_lock);
 
@@ -740,21 +660,15 @@ err_out:
  */
 void zfcp_port_dequeue(struct zfcp_port *port)
 {
-       zfcp_port_wait(port);
+       wait_event(port->remove_wq, atomic_read(&port->refcount) == 0);
        write_lock_irq(&zfcp_data.config_lock);
        list_del(&port->list);
-       port->adapter->ports--;
        write_unlock_irq(&zfcp_data.config_lock);
        if (port->rport)
                fc_remote_port_delete(port->rport);
        port->rport = NULL;
        zfcp_adapter_put(port->adapter);
-       if (atomic_read(&port->status) & ZFCP_STATUS_PORT_WKA)
-               sysfs_remove_group(&port->sysfs_device.kobj,
-                                  &zfcp_sysfs_ns_port_attrs);
-       else
-               sysfs_remove_group(&port->sysfs_device.kobj,
-                                  &zfcp_sysfs_port_attrs);
+       sysfs_remove_group(&port->sysfs_device.kobj, &zfcp_sysfs_port_attrs);
        device_unregister(&port->sysfs_device);
 }
 
index 51b6a05f4d12f107fca7cd6d40a1c4a186337828..b04038c74786b32456ded58505b96efd7f4c1756 100644 (file)
@@ -25,7 +25,8 @@ static int zfcp_ccw_probe(struct ccw_device *ccw_device)
        down(&zfcp_data.config_sema);
        if (zfcp_adapter_enqueue(ccw_device)) {
                dev_err(&ccw_device->dev,
-                       "Setup of data structures failed.\n");
+                       "Setting up data structures for the "
+                       "FCP adapter failed\n");
                retval = -EINVAL;
        }
        up(&zfcp_data.config_sema);
@@ -46,6 +47,8 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device)
        struct zfcp_adapter *adapter;
        struct zfcp_port *port, *p;
        struct zfcp_unit *unit, *u;
+       LIST_HEAD(unit_remove_lh);
+       LIST_HEAD(port_remove_lh);
 
        ccw_device_set_offline(ccw_device);
        down(&zfcp_data.config_sema);
@@ -54,26 +57,26 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device)
        write_lock_irq(&zfcp_data.config_lock);
        list_for_each_entry_safe(port, p, &adapter->port_list_head, list) {
                list_for_each_entry_safe(unit, u, &port->unit_list_head, list) {
-                       list_move(&unit->list, &port->unit_remove_lh);
+                       list_move(&unit->list, &unit_remove_lh);
                        atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE,
                                        &unit->status);
                }
-               list_move(&port->list, &adapter->port_remove_lh);
+               list_move(&port->list, &port_remove_lh);
                atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
        }
        atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
        write_unlock_irq(&zfcp_data.config_lock);
 
-       list_for_each_entry_safe(port, p, &adapter->port_remove_lh, list) {
-               list_for_each_entry_safe(unit, u, &port->unit_remove_lh, list) {
-                       if (atomic_test_mask(ZFCP_STATUS_UNIT_REGISTERED,
-                               &unit->status))
+       list_for_each_entry_safe(port, p, &port_remove_lh, list) {
+               list_for_each_entry_safe(unit, u, &unit_remove_lh, list) {
+                       if (atomic_read(&unit->status) &
+                           ZFCP_STATUS_UNIT_REGISTERED)
                                scsi_remove_device(unit->device);
                        zfcp_unit_dequeue(unit);
                }
                zfcp_port_dequeue(port);
        }
-       zfcp_adapter_wait(adapter);
+       wait_event(adapter->remove_wq, atomic_read(&adapter->refcount) == 0);
        zfcp_adapter_dequeue(adapter);
 
        up(&zfcp_data.config_sema);
@@ -156,15 +159,18 @@ static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event)
 
        switch (event) {
        case CIO_GONE:
-               dev_warn(&adapter->ccw_device->dev, "device gone\n");
+               dev_warn(&adapter->ccw_device->dev,
+                        "The FCP device has been detached\n");
                zfcp_erp_adapter_shutdown(adapter, 0, 87, NULL);
                break;
        case CIO_NO_PATH:
-               dev_warn(&adapter->ccw_device->dev, "no path\n");
+               dev_warn(&adapter->ccw_device->dev,
+                        "The CHPID for the FCP device is offline\n");
                zfcp_erp_adapter_shutdown(adapter, 0, 88, NULL);
                break;
        case CIO_OPER:
-               dev_info(&adapter->ccw_device->dev, "operational again\n");
+               dev_info(&adapter->ccw_device->dev,
+                        "The FCP device is operational again\n");
                zfcp_erp_modify_adapter_status(adapter, 11, NULL,
                                               ZFCP_STATUS_COMMON_RUNNING,
                                               ZFCP_SET);
@@ -220,3 +226,20 @@ int __init zfcp_ccw_register(void)
 {
        return ccw_driver_register(&zfcp_ccw_driver);
 }
+
+/**
+ * zfcp_get_adapter_by_busid - find zfcp_adapter struct
+ * @busid: bus id string of zfcp adapter to find
+ */
+struct zfcp_adapter *zfcp_get_adapter_by_busid(char *busid)
+{
+       struct ccw_device *ccw_device;
+       struct zfcp_adapter *adapter = NULL;
+
+       ccw_device = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
+       if (ccw_device) {
+               adapter = dev_get_drvdata(&ccw_device->dev);
+               put_device(&ccw_device->dev);
+       }
+       return adapter;
+}
index fca48b88fc53b662be4e85dce9aaec8a3038e293..060f5f2352ecb590b74e8667bb703fb1c0e62bc1 100644 (file)
@@ -318,6 +318,26 @@ void zfcp_hba_dbf_event_qdio(struct zfcp_adapter *adapter,
        spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
 }
 
+/**
+ * zfcp_hba_dbf_event_berr - trace event for bit error threshold
+ * @adapter: adapter affected by this QDIO related event
+ * @req: fsf request
+ */
+void zfcp_hba_dbf_event_berr(struct zfcp_adapter *adapter,
+                            struct zfcp_fsf_req *req)
+{
+       struct zfcp_hba_dbf_record *r = &adapter->hba_dbf_buf;
+       struct fsf_status_read_buffer *sr_buf = req->data;
+       struct fsf_bit_error_payload *err = &sr_buf->payload.bit_error;
+       unsigned long flags;
+
+       spin_lock_irqsave(&adapter->hba_dbf_lock, flags);
+       memset(r, 0, sizeof(*r));
+       strncpy(r->tag, "berr", ZFCP_DBF_TAG_SIZE);
+       memcpy(&r->u.berr, err, sizeof(struct fsf_bit_error_payload));
+       debug_event(adapter->hba_dbf, 0, r, sizeof(*r));
+       spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
+}
 static void zfcp_hba_dbf_view_response(char **p,
                                       struct zfcp_hba_dbf_record_response *r)
 {
@@ -399,6 +419,30 @@ static void zfcp_hba_dbf_view_qdio(char **p, struct zfcp_hba_dbf_record_qdio *r)
        zfcp_dbf_out(p, "sbal_count", "0x%02x", r->sbal_count);
 }
 
+static void zfcp_hba_dbf_view_berr(char **p, struct fsf_bit_error_payload *r)
+{
+       zfcp_dbf_out(p, "link_failures", "%d", r->link_failure_error_count);
+       zfcp_dbf_out(p, "loss_of_sync_err", "%d", r->loss_of_sync_error_count);
+       zfcp_dbf_out(p, "loss_of_sig_err", "%d", r->loss_of_signal_error_count);
+       zfcp_dbf_out(p, "prim_seq_err", "%d",
+                    r->primitive_sequence_error_count);
+       zfcp_dbf_out(p, "inval_trans_word_err", "%d",
+                    r->invalid_transmission_word_error_count);
+       zfcp_dbf_out(p, "CRC_errors", "%d", r->crc_error_count);
+       zfcp_dbf_out(p, "prim_seq_event_to", "%d",
+                    r->primitive_sequence_event_timeout_count);
+       zfcp_dbf_out(p, "elast_buf_overrun_err", "%d",
+                    r->elastic_buffer_overrun_error_count);
+       zfcp_dbf_out(p, "adv_rec_buf2buf_cred", "%d",
+                    r->advertised_receive_b2b_credit);
+       zfcp_dbf_out(p, "curr_rec_buf2buf_cred", "%d",
+                    r->current_receive_b2b_credit);
+       zfcp_dbf_out(p, "adv_trans_buf2buf_cred", "%d",
+                    r->advertised_transmit_b2b_credit);
+       zfcp_dbf_out(p, "curr_trans_buf2buf_cred", "%d",
+                    r->current_transmit_b2b_credit);
+}
+
 static int zfcp_hba_dbf_view_format(debug_info_t *id, struct debug_view *view,
                                    char *out_buf, const char *in_buf)
 {
@@ -418,6 +462,8 @@ static int zfcp_hba_dbf_view_format(debug_info_t *id, struct debug_view *view,
                zfcp_hba_dbf_view_status(&p, &r->u.status);
        else if (strncmp(r->tag, "qdio", ZFCP_DBF_TAG_SIZE) == 0)
                zfcp_hba_dbf_view_qdio(&p, &r->u.qdio);
+       else if (strncmp(r->tag, "berr", ZFCP_DBF_TAG_SIZE) == 0)
+               zfcp_hba_dbf_view_berr(&p, &r->u.berr);
 
        p += sprintf(p, "\n");
        return p - out_buf;
@@ -519,14 +565,14 @@ static const char *zfcp_rec_dbf_ids[] = {
        [75]    = "physical port recovery escalation after failed port "
                  "recovery",
        [76]    = "port recovery escalation after failed unit recovery",
-       [77]    = "recovery opening nameserver port",
+       [77]    = "",
        [78]    = "duplicate request id",
        [79]    = "link down",
        [80]    = "exclusive read-only unit access unsupported",
        [81]    = "shared read-write unit access unsupported",
        [82]    = "incoming rscn",
        [83]    = "incoming wwpn",
-       [84]    = "",
+       [84]    = "wka port handle not valid close port",
        [85]    = "online",
        [86]    = "offline",
        [87]    = "ccw device gone",
@@ -570,7 +616,7 @@ static const char *zfcp_rec_dbf_ids[] = {
        [125]   = "need newer zfcp",
        [126]   = "need newer microcode",
        [127]   = "arbitrated loop not supported",
-       [128]   = "unknown topology",
+       [128]   = "",
        [129]   = "qtcb size mismatch",
        [130]   = "unknown fsf status ecd",
        [131]   = "fcp request too big",
@@ -829,9 +875,9 @@ void zfcp_rec_dbf_event_action(u8 id2, struct zfcp_erp_action *erp_action)
 void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req)
 {
        struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;
-       struct zfcp_port *port = ct->port;
-       struct zfcp_adapter *adapter = port->adapter;
-       struct ct_hdr *hdr = zfcp_sg_to_address(ct->req);
+       struct zfcp_wka_port *wka_port = ct->wka_port;
+       struct zfcp_adapter *adapter = wka_port->adapter;
+       struct ct_hdr *hdr = sg_virt(ct->req);
        struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf;
        struct zfcp_san_dbf_record_ct_request *oct = &r->u.ct_req;
        unsigned long flags;
@@ -842,7 +888,7 @@ void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req)
        r->fsf_reqid = (unsigned long)fsf_req;
        r->fsf_seqno = fsf_req->seq_no;
        r->s_id = fc_host_port_id(adapter->scsi_host);
-       r->d_id = port->d_id;
+       r->d_id = wka_port->d_id;
        oct->cmd_req_code = hdr->cmd_rsp_code;
        oct->revision = hdr->revision;
        oct->gs_type = hdr->gs_type;
@@ -863,9 +909,9 @@ void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req)
 void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req)
 {
        struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;
-       struct zfcp_port *port = ct->port;
-       struct zfcp_adapter *adapter = port->adapter;
-       struct ct_hdr *hdr = zfcp_sg_to_address(ct->resp);
+       struct zfcp_wka_port *wka_port = ct->wka_port;
+       struct zfcp_adapter *adapter = wka_port->adapter;
+       struct ct_hdr *hdr = sg_virt(ct->resp);
        struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf;
        struct zfcp_san_dbf_record_ct_response *rct = &r->u.ct_resp;
        unsigned long flags;
@@ -875,7 +921,7 @@ void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req)
        strncpy(r->tag, "rctc", ZFCP_DBF_TAG_SIZE);
        r->fsf_reqid = (unsigned long)fsf_req;
        r->fsf_seqno = fsf_req->seq_no;
-       r->s_id = port->d_id;
+       r->s_id = wka_port->d_id;
        r->d_id = fc_host_port_id(adapter->scsi_host);
        rct->cmd_rsp_code = hdr->cmd_rsp_code;
        rct->revision = hdr->revision;
@@ -922,8 +968,8 @@ void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *fsf_req)
 
        zfcp_san_dbf_event_els("oels", 2, fsf_req,
                               fc_host_port_id(els->adapter->scsi_host),
-                              els->d_id, *(u8 *) zfcp_sg_to_address(els->req),
-                              zfcp_sg_to_address(els->req), els->req->length);
+                              els->d_id, *(u8 *) sg_virt(els->req),
+                              sg_virt(els->req), els->req->length);
 }
 
 /**
@@ -936,8 +982,7 @@ void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *fsf_req)
 
        zfcp_san_dbf_event_els("rels", 2, fsf_req, els->d_id,
                               fc_host_port_id(els->adapter->scsi_host),
-                              *(u8 *)zfcp_sg_to_address(els->req),
-                              zfcp_sg_to_address(els->resp),
+                              *(u8 *)sg_virt(els->req), sg_virt(els->resp),
                               els->resp->length);
 }
 
index 0ddb18449d11b190a602d628461d2f5f01dc564d..e8f450801fea7f1cd351b7dad1049d02f82ab238 100644 (file)
@@ -151,6 +151,7 @@ struct zfcp_hba_dbf_record {
                struct zfcp_hba_dbf_record_response response;
                struct zfcp_hba_dbf_record_status status;
                struct zfcp_hba_dbf_record_qdio qdio;
+               struct fsf_bit_error_payload berr;
        } u;
 } __attribute__ ((packed));
 
index 67f45fc62f53b3cad2e5df6b1ed86ee60046ecd7..73eb41580f25c40fe3dc41861703de5c9f9f2bb8 100644 (file)
 
 /********************* GENERAL DEFINES *********************************/
 
-/**
- * zfcp_sg_to_address - determine kernel address from struct scatterlist
- * @list: struct scatterlist
- * Return: kernel address
- */
-static inline void *
-zfcp_sg_to_address(struct scatterlist *list)
-{
-       return sg_virt(list);
-}
-
-/**
- * zfcp_address_to_sg - set up struct scatterlist from kernel address
- * @address: kernel address
- * @list: struct scatterlist
- * @size: buffer size
- */
-static inline void
-zfcp_address_to_sg(void *address, struct scatterlist *list, unsigned int size)
-{
-       sg_set_buf(list, address, size);
-}
-
 #define REQUEST_LIST_SIZE 128
 
 /********************* SCSI SPECIFIC DEFINES *********************************/
@@ -101,11 +78,6 @@ zfcp_address_to_sg(void *address, struct scatterlist *list, unsigned int size)
 
 /*************** FIBRE CHANNEL PROTOCOL SPECIFIC DEFINES ********************/
 
-typedef unsigned long long wwn_t;
-typedef unsigned long long fcp_lun_t;
-/* data length field may be at variable position in FCP-2 FCP_CMND IU */
-typedef unsigned int       fcp_dl_t;
-
 /* timeout for name-server lookup (in seconds) */
 #define ZFCP_NS_GID_PN_TIMEOUT         10
 
@@ -129,7 +101,7 @@ typedef unsigned int       fcp_dl_t;
 
 /* FCP(-2) FCP_CMND IU */
 struct fcp_cmnd_iu {
-       fcp_lun_t fcp_lun;         /* FCP logical unit number */
+       u64 fcp_lun;       /* FCP logical unit number */
        u8  crn;                   /* command reference number */
        u8  reserved0:5;           /* reserved */
        u8  task_attribute:3;      /* task attribute */
@@ -204,7 +176,7 @@ struct fcp_rscn_element {
 struct fcp_logo {
         u32 command;
         u32 nport_did;
-        wwn_t nport_wwpn;
+       u64 nport_wwpn;
 } __attribute__((packed));
 
 /*
@@ -218,13 +190,6 @@ struct fcp_logo {
 #define ZFCP_LS_RSCN                   0x61
 #define ZFCP_LS_RNID                   0x78
 
-struct zfcp_ls_rjt_par {
-       u8 action;
-       u8 reason_code;
-       u8 reason_expl;
-       u8 vendor_unique;
-} __attribute__ ((packed));
-
 struct zfcp_ls_adisc {
        u8              code;
        u8              field[3];
@@ -234,20 +199,6 @@ struct zfcp_ls_adisc {
        u32             nport_id;
 } __attribute__ ((packed));
 
-struct zfcp_ls_adisc_acc {
-       u8              code;
-       u8              field[3];
-       u32             hard_nport_id;
-       u64             wwpn;
-       u64             wwnn;
-       u32             nport_id;
-} __attribute__ ((packed));
-
-struct zfcp_rc_entry {
-       u8 code;
-       const char *description;
-};
-
 /*
  * FC-GS-2 stuff
  */
@@ -281,9 +232,7 @@ struct zfcp_rc_entry {
 #define ZFCP_STATUS_COMMON_RUNNING             0x40000000
 #define ZFCP_STATUS_COMMON_ERP_FAILED          0x20000000
 #define ZFCP_STATUS_COMMON_UNBLOCKED           0x10000000
-#define ZFCP_STATUS_COMMON_OPENING              0x08000000
 #define ZFCP_STATUS_COMMON_OPEN                 0x04000000
-#define ZFCP_STATUS_COMMON_CLOSING              0x02000000
 #define ZFCP_STATUS_COMMON_ERP_INUSE           0x01000000
 #define ZFCP_STATUS_COMMON_ACCESS_DENIED       0x00800000
 #define ZFCP_STATUS_COMMON_ACCESS_BOXED                0x00400000
@@ -291,16 +240,15 @@ struct zfcp_rc_entry {
 
 /* adapter status */
 #define ZFCP_STATUS_ADAPTER_QDIOUP             0x00000002
-#define ZFCP_STATUS_ADAPTER_REGISTERED         0x00000004
 #define ZFCP_STATUS_ADAPTER_XCONFIG_OK         0x00000008
 #define ZFCP_STATUS_ADAPTER_HOST_CON_INIT      0x00000010
 #define ZFCP_STATUS_ADAPTER_ERP_THREAD_UP      0x00000020
 #define ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL    0x00000080
 #define ZFCP_STATUS_ADAPTER_ERP_PENDING                0x00000100
 #define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED     0x00000200
-#define ZFCP_STATUS_ADAPTER_XPORT_OK           0x00000800
 
 /* FC-PH/FC-GS well-known address identifiers for generic services */
+#define ZFCP_DID_WKA                           0xFFFFF0
 #define ZFCP_DID_MANAGEMENT_SERVICE            0xFFFFFA
 #define ZFCP_DID_TIME_SERVICE                  0xFFFFFB
 #define ZFCP_DID_DIRECTORY_SERVICE             0xFFFFFC
@@ -312,29 +260,27 @@ struct zfcp_rc_entry {
 #define ZFCP_STATUS_PORT_DID_DID               0x00000002
 #define ZFCP_STATUS_PORT_PHYS_CLOSING          0x00000004
 #define ZFCP_STATUS_PORT_NO_WWPN               0x00000008
-#define ZFCP_STATUS_PORT_NO_SCSI_ID            0x00000010
 #define ZFCP_STATUS_PORT_INVALID_WWPN          0x00000020
 
-/* for ports with well known addresses */
-#define ZFCP_STATUS_PORT_WKA \
-               (ZFCP_STATUS_PORT_NO_WWPN | \
-                ZFCP_STATUS_PORT_NO_SCSI_ID)
+/* well known address (WKA) port status*/
+enum zfcp_wka_status {
+       ZFCP_WKA_PORT_OFFLINE,
+       ZFCP_WKA_PORT_CLOSING,
+       ZFCP_WKA_PORT_OPENING,
+       ZFCP_WKA_PORT_ONLINE,
+};
 
 /* logical unit status */
-#define ZFCP_STATUS_UNIT_TEMPORARY             0x00000002
 #define ZFCP_STATUS_UNIT_SHARED                        0x00000004
 #define ZFCP_STATUS_UNIT_READONLY              0x00000008
 #define ZFCP_STATUS_UNIT_REGISTERED            0x00000010
 #define ZFCP_STATUS_UNIT_SCSI_WORK_PENDING     0x00000020
 
 /* FSF request status (this does not have a common part) */
-#define ZFCP_STATUS_FSFREQ_NOT_INIT            0x00000000
-#define ZFCP_STATUS_FSFREQ_POOL                0x00000001
 #define ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT     0x00000002
 #define ZFCP_STATUS_FSFREQ_COMPLETED           0x00000004
 #define ZFCP_STATUS_FSFREQ_ERROR               0x00000008
 #define ZFCP_STATUS_FSFREQ_CLEANUP             0x00000010
-#define ZFCP_STATUS_FSFREQ_ABORTING            0x00000020
 #define ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED      0x00000040
 #define ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED       0x00000080
 #define ZFCP_STATUS_FSFREQ_ABORTED              0x00000100
@@ -379,7 +325,7 @@ struct ct_hdr {
  * a port name is required */
 struct ct_iu_gid_pn_req {
        struct ct_hdr header;
-       wwn_t wwpn;
+       u64 wwpn;
 } __attribute__ ((packed));
 
 /* FS_ACC IU and data unit for GID_PN nameserver request */
@@ -388,11 +334,9 @@ struct ct_iu_gid_pn_resp {
        u32 d_id;
 } __attribute__ ((packed));
 
-typedef void (*zfcp_send_ct_handler_t)(unsigned long);
-
 /**
  * struct zfcp_send_ct - used to pass parameters to function zfcp_fsf_send_ct
- * @port: port where the request is sent to
+ * @wka_port: port where the request is sent to
  * @req: scatter-gather list for request
  * @resp: scatter-gather list for response
  * @req_count: number of elements in request scatter-gather list
@@ -404,12 +348,12 @@ typedef void (*zfcp_send_ct_handler_t)(unsigned long);
  * @status: used to pass error status to calling function
  */
 struct zfcp_send_ct {
-       struct zfcp_port *port;
+       struct zfcp_wka_port *wka_port;
        struct scatterlist *req;
        struct scatterlist *resp;
        unsigned int req_count;
        unsigned int resp_count;
-       zfcp_send_ct_handler_t handler;
+       void (*handler)(unsigned long);
        unsigned long handler_data;
        int timeout;
        struct completion *completion;
@@ -426,8 +370,6 @@ struct zfcp_gid_pn_data {
         struct zfcp_port *port;
 };
 
-typedef void (*zfcp_send_els_handler_t)(unsigned long);
-
 /**
  * struct zfcp_send_els - used to pass parameters to function zfcp_fsf_send_els
  * @adapter: adapter where request is sent from
@@ -451,22 +393,28 @@ struct zfcp_send_els {
        struct scatterlist *resp;
        unsigned int req_count;
        unsigned int resp_count;
-       zfcp_send_els_handler_t handler;
+       void (*handler)(unsigned long);
        unsigned long handler_data;
        struct completion *completion;
        int ls_code;
        int status;
 };
 
+struct zfcp_wka_port {
+       struct zfcp_adapter     *adapter;
+       wait_queue_head_t       completion_wq;
+       enum zfcp_wka_status    status;
+       atomic_t                refcount;
+       u32                     d_id;
+       u32                     handle;
+       struct mutex            mutex;
+       struct delayed_work     work;
+};
+
 struct zfcp_qdio_queue {
-       struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q]; /* SBALs */
-       u8                 first;             /* index of next free bfr
-                                                in queue (free_count>0) */
-       atomic_t           count;             /* number of free buffers
-                                                in queue */
-       spinlock_t         lock;              /* lock for operations on queue */
-       int                pci_batch;         /* SBALs since PCI indication
-                                                was last set */
+       struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q];
+       u8                 first;       /* index of next free bfr in queue */
+       atomic_t           count;       /* number of free buffers in queue */
 };
 
 struct zfcp_erp_action {
@@ -475,7 +423,7 @@ struct zfcp_erp_action {
        struct zfcp_adapter *adapter; /* device which should be recovered */
        struct zfcp_port *port;
        struct zfcp_unit *unit;
-       volatile u32 status;          /* recovery status */
+       u32             status;       /* recovery status */
        u32 step;                     /* active step of this erp action */
        struct zfcp_fsf_req *fsf_req; /* fsf request currently pending
                                         for this action */
@@ -506,8 +454,8 @@ struct zfcp_adapter {
        atomic_t                refcount;          /* reference count */
        wait_queue_head_t       remove_wq;         /* can be used to wait for
                                                      refcount drop to zero */
-       wwn_t                   peer_wwnn;         /* P2P peer WWNN */
-       wwn_t                   peer_wwpn;         /* P2P peer WWPN */
+       u64                     peer_wwnn;         /* P2P peer WWNN */
+       u64                     peer_wwpn;         /* P2P peer WWPN */
        u32                     peer_d_id;         /* P2P peer D_ID */
        struct ccw_device       *ccw_device;       /* S/390 ccw device */
        u32                     hydra_version;     /* Hydra version */
@@ -518,13 +466,13 @@ struct zfcp_adapter {
        u16                     timer_ticks;       /* time int for a tick */
        struct Scsi_Host        *scsi_host;        /* Pointer to mid-layer */
        struct list_head        port_list_head;    /* remote port list */
-       struct list_head        port_remove_lh;    /* head of ports to be
-                                                     removed */
-       u32                     ports;             /* number of remote ports */
        unsigned long           req_no;            /* unique FSF req number */
        struct list_head        *req_list;         /* list of pending reqs */
        spinlock_t              req_list_lock;     /* request list lock */
        struct zfcp_qdio_queue  req_q;             /* request queue */
+       spinlock_t              req_q_lock;        /* for operations on queue */
+       int                     req_q_pci_batch;   /* SBALs since PCI indication
+                                                     was last set */
        u32                     fsf_req_seq_no;    /* FSF cmnd seq number */
        wait_queue_head_t       request_wq;        /* can be used to wait for
                                                      more avaliable SBALs */
@@ -548,7 +496,7 @@ struct zfcp_adapter {
                                                      actions */
        u32                     erp_low_mem_count; /* nr of erp actions waiting
                                                      for memory */
-       struct zfcp_port        *nameserver_port;  /* adapter's nameserver */
+       struct zfcp_wka_port    nsp;               /* adapter's nameserver */
        debug_info_t            *rec_dbf;
        debug_info_t            *hba_dbf;
        debug_info_t            *san_dbf;          /* debug feature areas */
@@ -563,11 +511,11 @@ struct zfcp_adapter {
        struct zfcp_scsi_dbf_record     scsi_dbf_buf;
        struct zfcp_adapter_mempool     pool;      /* Adapter memory pools */
        struct qdio_initialize  qdio_init_data;    /* for qdio_establish */
-       struct device           generic_services;  /* directory for WKA ports */
        struct fc_host_statistics *fc_stats;
        struct fsf_qtcb_bottom_port *stats_reset_data;
        unsigned long           stats_reset;
        struct work_struct      scan_work;
+       atomic_t                qdio_outb_full;    /* queue full incidents */
 };
 
 struct zfcp_port {
@@ -579,18 +527,16 @@ struct zfcp_port {
                                                  refcount drop to zero */
        struct zfcp_adapter    *adapter;       /* adapter used to access port */
        struct list_head       unit_list_head; /* head of logical unit list */
-       struct list_head       unit_remove_lh; /* head of luns to be removed
-                                                 list */
-       u32                    units;          /* # of logical units in list */
        atomic_t               status;         /* status of this remote port */
-       wwn_t                  wwnn;           /* WWNN if known */
-       wwn_t                  wwpn;           /* WWPN */
+       u64                    wwnn;           /* WWNN if known */
+       u64                    wwpn;           /* WWPN */
        u32                    d_id;           /* D_ID */
        u32                    handle;         /* handle assigned by FSF */
        struct zfcp_erp_action erp_action;     /* pending error recovery */
         atomic_t               erp_counter;
        u32                    maxframe_size;
        u32                    supported_classes;
+       struct work_struct     gid_pn_work;
 };
 
 struct zfcp_unit {
@@ -601,8 +547,7 @@ struct zfcp_unit {
                                                  refcount drop to zero */
        struct zfcp_port       *port;          /* remote port of unit */
        atomic_t               status;         /* status of this logical unit */
-       unsigned int           scsi_lun;       /* own SCSI LUN */
-       fcp_lun_t              fcp_lun;        /* own FCP_LUN */
+       u64                    fcp_lun;        /* own FCP_LUN */
        u32                    handle;         /* handle assigned by FSF */
         struct scsi_device     *device;        /* scsi device struct pointer */
        struct zfcp_erp_action erp_action;     /* pending error recovery */
@@ -625,7 +570,7 @@ struct zfcp_fsf_req {
        u8                      sbal_response;  /* SBAL used in interrupt */
        wait_queue_head_t      completion_wq;  /* can be used by a routine
                                                  to wait for completion */
-       volatile u32           status;         /* status of this request */
+       u32                     status;        /* status of this request */
        u32                    fsf_command;    /* FSF Command copy */
        struct fsf_qtcb        *qtcb;          /* address of associated QTCB */
        u32                    seq_no;         /* Sequence number of request */
@@ -644,11 +589,7 @@ struct zfcp_fsf_req {
 struct zfcp_data {
        struct scsi_host_template scsi_host_template;
        struct scsi_transport_template *scsi_transport_template;
-        atomic_t                status;             /* Module status flags */
        struct list_head        adapter_list_head;  /* head of adapter list */
-       struct list_head        adapter_remove_lh;  /* head of adapters to be
-                                                      removed */
-       u32                     adapters;           /* # of adapters in list */
        rwlock_t                config_lock;        /* serialises changes
                                                       to adapter/port/unit
                                                       lists */
@@ -656,11 +597,12 @@ struct zfcp_data {
                                                       changes */
        atomic_t                loglevel;            /* current loglevel */
        char                    init_busid[BUS_ID_SIZE];
-       wwn_t                   init_wwpn;
-       fcp_lun_t               init_fcp_lun;
-       struct kmem_cache               *fsf_req_qtcb_cache;
-       struct kmem_cache               *sr_buffer_cache;
-       struct kmem_cache               *gid_pn_cache;
+       u64                     init_wwpn;
+       u64                     init_fcp_lun;
+       struct kmem_cache       *fsf_req_qtcb_cache;
+       struct kmem_cache       *sr_buffer_cache;
+       struct kmem_cache       *gid_pn_cache;
+       struct workqueue_struct *work_queue;
 };
 
 /* struct used by memory pools for fsf_requests */
@@ -677,14 +619,7 @@ struct zfcp_fsf_req_qtcb {
 #define ZFCP_SET                0x00000100
 #define ZFCP_CLEAR              0x00000200
 
-#ifndef atomic_test_mask
-#define atomic_test_mask(mask, target) \
-           ((atomic_read(target) & mask) == mask)
-#endif
-
 #define zfcp_get_busid_by_adapter(adapter) (adapter->ccw_device->dev.bus_id)
-#define zfcp_get_busid_by_port(port) (zfcp_get_busid_by_adapter(port->adapter))
-#define zfcp_get_busid_by_unit(unit) (zfcp_get_busid_by_port(unit->port))
 
 /*
  * Helper functions for request ID management.
@@ -744,12 +679,6 @@ zfcp_unit_put(struct zfcp_unit *unit)
                wake_up(&unit->remove_wq);
 }
 
-static inline void
-zfcp_unit_wait(struct zfcp_unit *unit)
-{
-       wait_event(unit->remove_wq, atomic_read(&unit->refcount) == 0);
-}
-
 static inline void
 zfcp_port_get(struct zfcp_port *port)
 {
@@ -763,12 +692,6 @@ zfcp_port_put(struct zfcp_port *port)
                wake_up(&port->remove_wq);
 }
 
-static inline void
-zfcp_port_wait(struct zfcp_port *port)
-{
-       wait_event(port->remove_wq, atomic_read(&port->refcount) == 0);
-}
-
 static inline void
 zfcp_adapter_get(struct zfcp_adapter *adapter)
 {
@@ -782,10 +705,4 @@ zfcp_adapter_put(struct zfcp_adapter *adapter)
                wake_up(&adapter->remove_wq);
 }
 
-static inline void
-zfcp_adapter_wait(struct zfcp_adapter *adapter)
-{
-       wait_event(adapter->remove_wq, atomic_read(&adapter->refcount) == 0);
-}
-
 #endif /* ZFCP_DEF_H */
index 643ac4bba5b552085e7f4aeb94aeffa3d51c7ffc..782313131870ad928bc9a9a4072a5d3e5503ec02 100644 (file)
@@ -23,7 +23,6 @@ enum zfcp_erp_steps {
        ZFCP_ERP_STEP_FSF_XCONFIG       = 0x0001,
        ZFCP_ERP_STEP_PHYS_PORT_CLOSING = 0x0010,
        ZFCP_ERP_STEP_PORT_CLOSING      = 0x0100,
-       ZFCP_ERP_STEP_NAMESERVER_OPEN   = 0x0200,
        ZFCP_ERP_STEP_NAMESERVER_LOOKUP = 0x0400,
        ZFCP_ERP_STEP_PORT_OPENING      = 0x0800,
        ZFCP_ERP_STEP_UNIT_CLOSING      = 0x1000,
@@ -532,8 +531,7 @@ static void _zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter,
        struct zfcp_port *port;
 
        list_for_each_entry(port, &adapter->port_list_head, list)
-               if (!(atomic_read(&port->status) & ZFCP_STATUS_PORT_WKA))
-                       _zfcp_erp_port_reopen(port, clear, id, ref);
+               _zfcp_erp_port_reopen(port, clear, id, ref);
 }
 
 static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear, u8 id,
@@ -669,8 +667,6 @@ static int zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *act)
        int ret;
        struct zfcp_adapter *adapter = act->adapter;
 
-       atomic_clear_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status);
-
        write_lock_irq(&adapter->erp_lock);
        zfcp_erp_action_to_running(act);
        write_unlock_irq(&adapter->erp_lock);
@@ -741,8 +737,7 @@ static int zfcp_erp_adapter_strategy_generic(struct zfcp_erp_action *act,
                                       ZFCP_STATUS_COMMON_OPEN, ZFCP_CLEAR);
  failed_qdio:
        atomic_clear_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK |
-                         ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
-                         ZFCP_STATUS_ADAPTER_XPORT_OK,
+                         ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
                          &act->adapter->status);
        return retval;
 }
@@ -751,15 +746,11 @@ static int zfcp_erp_adapter_strategy(struct zfcp_erp_action *act)
 {
        int retval;
 
-       atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING, &act->adapter->status);
        zfcp_erp_adapter_strategy_generic(act, 1); /* close */
-       atomic_clear_mask(ZFCP_STATUS_COMMON_CLOSING, &act->adapter->status);
        if (act->status & ZFCP_STATUS_ERP_CLOSE_ONLY)
                return ZFCP_ERP_EXIT;
 
-       atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &act->adapter->status);
        retval = zfcp_erp_adapter_strategy_generic(act, 0); /* open */
-       atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING, &act->adapter->status);
 
        if (retval == ZFCP_ERP_FAILED)
                ssleep(8);
@@ -783,10 +774,7 @@ static int zfcp_erp_port_forced_strategy_close(struct zfcp_erp_action *act)
 
 static void zfcp_erp_port_strategy_clearstati(struct zfcp_port *port)
 {
-       atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING |
-                         ZFCP_STATUS_COMMON_CLOSING |
-                         ZFCP_STATUS_COMMON_ACCESS_DENIED |
-                         ZFCP_STATUS_PORT_DID_DID |
+       atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED |
                          ZFCP_STATUS_PORT_PHYS_CLOSING |
                          ZFCP_STATUS_PORT_INVALID_WWPN,
                          &port->status);
@@ -839,73 +827,12 @@ static int zfcp_erp_port_strategy_open_port(struct zfcp_erp_action *erp_action)
        return ZFCP_ERP_CONTINUES;
 }
 
-static void zfcp_erp_port_strategy_open_ns_wake(struct zfcp_erp_action *ns_act)
-{
-       unsigned long flags;
-       struct zfcp_adapter *adapter = ns_act->adapter;
-       struct zfcp_erp_action *act, *tmp;
-       int status;
-
-       read_lock_irqsave(&adapter->erp_lock, flags);
-       list_for_each_entry_safe(act, tmp, &adapter->erp_running_head, list) {
-               if (act->step == ZFCP_ERP_STEP_NAMESERVER_OPEN) {
-                       status = atomic_read(&adapter->nameserver_port->status);
-                       if (status & ZFCP_STATUS_COMMON_ERP_FAILED)
-                               zfcp_erp_port_failed(act->port, 27, NULL);
-                       zfcp_erp_action_ready(act);
-               }
-       }
-       read_unlock_irqrestore(&adapter->erp_lock, flags);
-}
-
-static int zfcp_erp_port_strategy_open_nameserver(struct zfcp_erp_action *act)
-{
-       int retval;
-
-       switch (act->step) {
-       case ZFCP_ERP_STEP_UNINITIALIZED:
-       case ZFCP_ERP_STEP_PHYS_PORT_CLOSING:
-       case ZFCP_ERP_STEP_PORT_CLOSING:
-               return zfcp_erp_port_strategy_open_port(act);
-
-       case ZFCP_ERP_STEP_PORT_OPENING:
-               if (atomic_read(&act->port->status) & ZFCP_STATUS_COMMON_OPEN)
-                       retval = ZFCP_ERP_SUCCEEDED;
-               else
-                       retval = ZFCP_ERP_FAILED;
-               /* this is needed anyway  */
-               zfcp_erp_port_strategy_open_ns_wake(act);
-               return retval;
-
-       default:
-               return ZFCP_ERP_FAILED;
-       }
-}
-
-static int zfcp_erp_port_strategy_open_lookup(struct zfcp_erp_action *act)
-{
-       int retval;
-
-       retval = zfcp_fc_ns_gid_pn_request(act);
-       if (retval == -ENOMEM)
-               return ZFCP_ERP_NOMEM;
-       act->step = ZFCP_ERP_STEP_NAMESERVER_LOOKUP;
-       if (retval)
-               return ZFCP_ERP_FAILED;
-       return ZFCP_ERP_CONTINUES;
-}
-
 static int zfcp_erp_open_ptp_port(struct zfcp_erp_action *act)
 {
        struct zfcp_adapter *adapter = act->adapter;
        struct zfcp_port *port = act->port;
 
        if (port->wwpn != adapter->peer_wwpn) {
-               dev_err(&adapter->ccw_device->dev,
-                       "Failed to open port 0x%016Lx, "
-                       "Peer WWPN 0x%016Lx does not "
-                       "match.\n", port->wwpn,
-                       adapter->peer_wwpn);
                zfcp_erp_port_failed(port, 25, NULL);
                return ZFCP_ERP_FAILED;
        }
@@ -914,11 +841,25 @@ static int zfcp_erp_open_ptp_port(struct zfcp_erp_action *act)
        return zfcp_erp_port_strategy_open_port(act);
 }
 
+void zfcp_erp_port_strategy_open_lookup(struct work_struct *work)
+{
+       int retval;
+       struct zfcp_port *port = container_of(work, struct zfcp_port,
+                                             gid_pn_work);
+
+       retval = zfcp_fc_ns_gid_pn(&port->erp_action);
+       if (retval == -ENOMEM)
+               zfcp_erp_notify(&port->erp_action, ZFCP_ERP_NOMEM);
+       port->erp_action.step = ZFCP_ERP_STEP_NAMESERVER_LOOKUP;
+       if (retval)
+               zfcp_erp_notify(&port->erp_action, ZFCP_ERP_FAILED);
+
+}
+
 static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
 {
        struct zfcp_adapter *adapter = act->adapter;
        struct zfcp_port *port = act->port;
-       struct zfcp_port *ns_port = adapter->nameserver_port;
        int p_status = atomic_read(&port->status);
 
        switch (act->step) {
@@ -927,28 +868,10 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
        case ZFCP_ERP_STEP_PORT_CLOSING:
                if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP)
                        return zfcp_erp_open_ptp_port(act);
-               if (!ns_port) {
-                       dev_err(&adapter->ccw_device->dev,
-                               "Nameserver port unavailable.\n");
-                       return ZFCP_ERP_FAILED;
-               }
-               if (!(atomic_read(&ns_port->status) &
-                     ZFCP_STATUS_COMMON_UNBLOCKED)) {
-                       /* nameserver port may live again */
-                       atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING,
-                                       &ns_port->status);
-                       if (zfcp_erp_port_reopen(ns_port, 0, 77, act) >= 0) {
-                               act->step = ZFCP_ERP_STEP_NAMESERVER_OPEN;
-                               return ZFCP_ERP_CONTINUES;
-                       }
-                       return ZFCP_ERP_FAILED;
+               if (!(p_status & ZFCP_STATUS_PORT_DID_DID)) {
+                       queue_work(zfcp_data.work_queue, &port->gid_pn_work);
+                       return ZFCP_ERP_CONTINUES;
                }
-               /* else nameserver port is already open, fall through */
-       case ZFCP_ERP_STEP_NAMESERVER_OPEN:
-               if (!(atomic_read(&ns_port->status) & ZFCP_STATUS_COMMON_OPEN))
-                       return ZFCP_ERP_FAILED;
-               return zfcp_erp_port_strategy_open_lookup(act);
-
        case ZFCP_ERP_STEP_NAMESERVER_LOOKUP:
                if (!(p_status & ZFCP_STATUS_PORT_DID_DID)) {
                        if (p_status & (ZFCP_STATUS_PORT_INVALID_WWPN)) {
@@ -961,25 +884,26 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
 
        case ZFCP_ERP_STEP_PORT_OPENING:
                /* D_ID might have changed during open */
-               if ((p_status & ZFCP_STATUS_COMMON_OPEN) &&
-                   (p_status & ZFCP_STATUS_PORT_DID_DID))
-                       return ZFCP_ERP_SUCCEEDED;
+               if (p_status & ZFCP_STATUS_COMMON_OPEN) {
+                       if (p_status & ZFCP_STATUS_PORT_DID_DID)
+                               return ZFCP_ERP_SUCCEEDED;
+                       else {
+                               act->step = ZFCP_ERP_STEP_PORT_CLOSING;
+                               return ZFCP_ERP_CONTINUES;
+                       }
                /* fall through otherwise */
+               }
        }
        return ZFCP_ERP_FAILED;
 }
 
-static int zfcp_erp_port_strategy_open(struct zfcp_erp_action *act)
-{
-       if (atomic_read(&act->port->status) & (ZFCP_STATUS_PORT_WKA))
-               return zfcp_erp_port_strategy_open_nameserver(act);
-       return zfcp_erp_port_strategy_open_common(act);
-}
-
 static int zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action)
 {
        struct zfcp_port *port = erp_action->port;
 
+       if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_NOESC)
+               goto close_init_done;
+
        switch (erp_action->step) {
        case ZFCP_ERP_STEP_UNINITIALIZED:
                zfcp_erp_port_strategy_clearstati(port);
@@ -992,19 +916,17 @@ static int zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action)
                        return ZFCP_ERP_FAILED;
                break;
        }
+
+close_init_done:
        if (erp_action->status & ZFCP_STATUS_ERP_CLOSE_ONLY)
                return ZFCP_ERP_EXIT;
-       else
-               return zfcp_erp_port_strategy_open(erp_action);
 
-       return ZFCP_ERP_FAILED;
+       return zfcp_erp_port_strategy_open_common(erp_action);
 }
 
 static void zfcp_erp_unit_strategy_clearstati(struct zfcp_unit *unit)
 {
-       atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING |
-                         ZFCP_STATUS_COMMON_CLOSING |
-                         ZFCP_STATUS_COMMON_ACCESS_DENIED |
+       atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED |
                          ZFCP_STATUS_UNIT_SHARED |
                          ZFCP_STATUS_UNIT_READONLY,
                          &unit->status);
@@ -1065,8 +987,14 @@ static int zfcp_erp_strategy_check_unit(struct zfcp_unit *unit, int result)
                break;
        case ZFCP_ERP_FAILED :
                atomic_inc(&unit->erp_counter);
-               if (atomic_read(&unit->erp_counter) > ZFCP_MAX_ERPS)
+               if (atomic_read(&unit->erp_counter) > ZFCP_MAX_ERPS) {
+                       dev_err(&unit->port->adapter->ccw_device->dev,
+                               "ERP failed for unit 0x%016Lx on "
+                               "port 0x%016Lx\n",
+                               (unsigned long long)unit->fcp_lun,
+                               (unsigned long long)unit->port->wwpn);
                        zfcp_erp_unit_failed(unit, 21, NULL);
+               }
                break;
        }
 
@@ -1091,8 +1019,12 @@ static int zfcp_erp_strategy_check_port(struct zfcp_port *port, int result)
                        result = ZFCP_ERP_EXIT;
                }
                atomic_inc(&port->erp_counter);
-               if (atomic_read(&port->erp_counter) > ZFCP_MAX_ERPS)
+               if (atomic_read(&port->erp_counter) > ZFCP_MAX_ERPS) {
+                       dev_err(&port->adapter->ccw_device->dev,
+                               "ERP failed for remote port 0x%016Lx\n",
+                               (unsigned long long)port->wwpn);
                        zfcp_erp_port_failed(port, 22, NULL);
+               }
                break;
        }
 
@@ -1114,8 +1046,12 @@ static int zfcp_erp_strategy_check_adapter(struct zfcp_adapter *adapter,
 
        case ZFCP_ERP_FAILED :
                atomic_inc(&adapter->erp_counter);
-               if (atomic_read(&adapter->erp_counter) > ZFCP_MAX_ERPS)
+               if (atomic_read(&adapter->erp_counter) > ZFCP_MAX_ERPS) {
+                       dev_err(&adapter->ccw_device->dev,
+                               "ERP cannot recover an error "
+                               "on the FCP device\n");
                        zfcp_erp_adapter_failed(adapter, 23, NULL);
+               }
                break;
        }
 
@@ -1250,9 +1186,10 @@ static void zfcp_erp_scsi_scan(struct work_struct *work)
        struct zfcp_unit *unit = p->unit;
        struct fc_rport *rport = unit->port->rport;
        scsi_scan_target(&rport->dev, 0, rport->scsi_target_id,
-                        unit->scsi_lun, 0);
+                        scsilun_to_int((struct scsi_lun *)&unit->fcp_lun), 0);
        atomic_clear_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status);
        zfcp_unit_put(unit);
+       wake_up(&unit->port->adapter->erp_done_wqh);
        kfree(p);
 }
 
@@ -1263,9 +1200,9 @@ static void zfcp_erp_schedule_work(struct zfcp_unit *unit)
        p = kzalloc(sizeof(*p), GFP_KERNEL);
        if (!p) {
                dev_err(&unit->port->adapter->ccw_device->dev,
-                       "Out of resources. Could not register unit "
-                       "0x%016Lx on port 0x%016Lx with SCSI stack.\n",
-                       unit->fcp_lun, unit->port->wwpn);
+                       "Registering unit 0x%016Lx on port 0x%016Lx failed\n",
+                       (unsigned long long)unit->fcp_lun,
+                       (unsigned long long)unit->port->wwpn);
                return;
        }
 
@@ -1273,7 +1210,7 @@ static void zfcp_erp_schedule_work(struct zfcp_unit *unit)
        atomic_set_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status);
        INIT_WORK(&p->work, zfcp_erp_scsi_scan);
        p->unit = unit;
-       schedule_work(&p->work);
+       queue_work(zfcp_data.work_queue, &p->work);
 }
 
 static void zfcp_erp_rport_register(struct zfcp_port *port)
@@ -1286,8 +1223,8 @@ static void zfcp_erp_rport_register(struct zfcp_port *port)
        port->rport = fc_remote_port_add(port->adapter->scsi_host, 0, &ids);
        if (!port->rport) {
                dev_err(&port->adapter->ccw_device->dev,
-                       "Failed registration of rport "
-                       "0x%016Lx.\n", port->wwpn);
+                       "Registering port 0x%016Lx failed\n",
+                       (unsigned long long)port->wwpn);
                return;
        }
 
@@ -1299,12 +1236,12 @@ static void zfcp_erp_rport_register(struct zfcp_port *port)
 static void zfcp_erp_rports_del(struct zfcp_adapter *adapter)
 {
        struct zfcp_port *port;
-       list_for_each_entry(port, &adapter->port_list_head, list)
-               if (port->rport && !(atomic_read(&port->status) &
-                                       ZFCP_STATUS_PORT_WKA)) {
-                       fc_remote_port_delete(port->rport);
-                       port->rport = NULL;
-               }
+       list_for_each_entry(port, &adapter->port_list_head, list) {
+               if (!port->rport)
+                       continue;
+               fc_remote_port_delete(port->rport);
+               port->rport = NULL;
+       }
 }
 
 static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
@@ -1459,9 +1396,9 @@ static int zfcp_erp_thread(void *data)
                                zfcp_erp_wakeup(adapter);
                }
 
-               zfcp_rec_dbf_event_thread(4, adapter);
+               zfcp_rec_dbf_event_thread_lock(4, adapter);
                down_interruptible(&adapter->erp_ready_sem);
-               zfcp_rec_dbf_event_thread(5, adapter);
+               zfcp_rec_dbf_event_thread_lock(5, adapter);
        }
 
        atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status);
@@ -1484,7 +1421,7 @@ int zfcp_erp_thread_setup(struct zfcp_adapter *adapter)
        retval = kernel_thread(zfcp_erp_thread, adapter, SIGCHLD);
        if (retval < 0) {
                dev_err(&adapter->ccw_device->dev,
-                       "Creation of ERP thread failed.\n");
+                       "Creating an ERP thread for the FCP device failed.\n");
                return retval;
        }
        wait_event(adapter->erp_thread_wqh,
@@ -1506,7 +1443,7 @@ void zfcp_erp_thread_kill(struct zfcp_adapter *adapter)
 {
        atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL, &adapter->status);
        up(&adapter->erp_ready_sem);
-       zfcp_rec_dbf_event_thread_lock(2, adapter);
+       zfcp_rec_dbf_event_thread_lock(3, adapter);
 
        wait_event(adapter->erp_thread_wqh,
                   !(atomic_read(&adapter->status) &
@@ -1526,7 +1463,6 @@ void zfcp_erp_adapter_failed(struct zfcp_adapter *adapter, u8 id, void *ref)
 {
        zfcp_erp_modify_adapter_status(adapter, id, ref,
                                       ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET);
-       dev_err(&adapter->ccw_device->dev, "Adapter ERP failed.\n");
 }
 
 /**
@@ -1539,15 +1475,6 @@ void zfcp_erp_port_failed(struct zfcp_port *port, u8 id, void *ref)
 {
        zfcp_erp_modify_port_status(port, id, ref,
                                    ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET);
-
-       if (atomic_read(&port->status) & ZFCP_STATUS_PORT_WKA)
-               dev_err(&port->adapter->ccw_device->dev,
-                       "Port ERP failed for WKA port d_id=0x%06x.\n",
-                       port->d_id);
-       else
-               dev_err(&port->adapter->ccw_device->dev,
-                       "Port ERP failed for port wwpn=0x%016Lx.\n",
-                       port->wwpn);
 }
 
 /**
@@ -1560,10 +1487,6 @@ void zfcp_erp_unit_failed(struct zfcp_unit *unit, u8 id, void *ref)
 {
        zfcp_erp_modify_unit_status(unit, id, ref,
                                    ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET);
-
-       dev_err(&unit->port->adapter->ccw_device->dev,
-               "Unit ERP failed for unit 0x%016Lx on port 0x%016Lx.\n",
-               unit->fcp_lun, unit->port->wwpn);
 }
 
 /**
@@ -1754,9 +1677,8 @@ static void zfcp_erp_port_access_changed(struct zfcp_port *port, u8 id,
 
        if (!(status & (ZFCP_STATUS_COMMON_ACCESS_DENIED |
                        ZFCP_STATUS_COMMON_ACCESS_BOXED))) {
-               if (!(status & ZFCP_STATUS_PORT_WKA))
-                       list_for_each_entry(unit, &port->unit_list_head, list)
-                               zfcp_erp_unit_access_changed(unit, id, ref);
+               list_for_each_entry(unit, &port->unit_list_head, list)
+                                   zfcp_erp_unit_access_changed(unit, id, ref);
                return;
        }
 
@@ -1779,10 +1701,7 @@ void zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter, u8 id,
                return;
 
        read_lock_irqsave(&zfcp_data.config_lock, flags);
-       if (adapter->nameserver_port)
-               zfcp_erp_port_access_changed(adapter->nameserver_port, id, ref);
        list_for_each_entry(port, &adapter->port_list_head, list)
-               if (port != adapter->nameserver_port)
-                       zfcp_erp_port_access_changed(port, id, ref);
+               zfcp_erp_port_access_changed(port, id, ref);
        read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 }
index edfdb21591f32427ef670e4c1274ea3c28035060..b5adeda93e1df562106979546b39614740ba1575 100644 (file)
 #include "zfcp_def.h"
 
 /* zfcp_aux.c */
-extern struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *,
-                                             fcp_lun_t);
-extern struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *,
-                                              wwn_t);
+extern struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *, u64);
+extern struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *, u64);
 extern int zfcp_adapter_enqueue(struct ccw_device *);
 extern void zfcp_adapter_dequeue(struct zfcp_adapter *);
-extern struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *, wwn_t, u32,
+extern struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *, u64, u32,
                                           u32);
 extern void zfcp_port_dequeue(struct zfcp_port *);
-extern struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *, fcp_lun_t);
+extern struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *, u64);
 extern void zfcp_unit_dequeue(struct zfcp_unit *);
 extern int zfcp_reqlist_isempty(struct zfcp_adapter *);
 extern void zfcp_sg_free_table(struct scatterlist *, int);
@@ -29,6 +27,7 @@ extern int zfcp_sg_setup_table(struct scatterlist *, int);
 
 /* zfcp_ccw.c */
 extern int zfcp_ccw_register(void);
+extern struct zfcp_adapter *zfcp_get_adapter_by_busid(char *);
 
 /* zfcp_cfdc.c */
 extern struct miscdevice zfcp_cfdc_misc;
@@ -50,6 +49,8 @@ extern void zfcp_hba_dbf_event_fsf_unsol(const char *, struct zfcp_adapter *,
                                         struct fsf_status_read_buffer *);
 extern void zfcp_hba_dbf_event_qdio(struct zfcp_adapter *, unsigned int, int,
                                    int);
+extern void zfcp_hba_dbf_event_berr(struct zfcp_adapter *,
+                                   struct zfcp_fsf_req *);
 extern void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *);
 extern void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *);
 extern void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *);
@@ -91,17 +92,21 @@ extern void zfcp_erp_port_access_denied(struct zfcp_port *, u8, void *);
 extern void zfcp_erp_unit_access_denied(struct zfcp_unit *, u8, void *);
 extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *, u8, void *);
 extern void zfcp_erp_timeout_handler(unsigned long);
+extern void zfcp_erp_port_strategy_open_lookup(struct work_struct *);
 
 /* zfcp_fc.c */
 extern int zfcp_scan_ports(struct zfcp_adapter *);
 extern void _zfcp_scan_ports_later(struct work_struct *);
 extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *);
-extern int zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *);
+extern int zfcp_fc_ns_gid_pn(struct zfcp_erp_action *);
 extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *);
 extern void zfcp_test_link(struct zfcp_port *);
+extern void zfcp_fc_nameserver_init(struct zfcp_adapter *);
 
 /* zfcp_fsf.c */
 extern int zfcp_fsf_open_port(struct zfcp_erp_action *);
+extern int zfcp_fsf_open_wka_port(struct zfcp_wka_port *);
+extern int zfcp_fsf_close_wka_port(struct zfcp_wka_port *);
 extern int zfcp_fsf_close_port(struct zfcp_erp_action *);
 extern int zfcp_fsf_close_physical_port(struct zfcp_erp_action *);
 extern int zfcp_fsf_open_unit(struct zfcp_erp_action *);
@@ -135,10 +140,8 @@ extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long,
 extern int zfcp_qdio_allocate(struct zfcp_adapter *);
 extern void zfcp_qdio_free(struct zfcp_adapter *);
 extern int zfcp_qdio_send(struct zfcp_fsf_req *);
-extern volatile struct qdio_buffer_element *zfcp_qdio_sbale_req(
-                                               struct zfcp_fsf_req *);
-extern volatile struct qdio_buffer_element *zfcp_qdio_sbale_curr(
-                                               struct zfcp_fsf_req *);
+extern struct qdio_buffer_element *zfcp_qdio_sbale_req(struct zfcp_fsf_req *);
+extern struct qdio_buffer_element *zfcp_qdio_sbale_curr(struct zfcp_fsf_req *);
 extern int zfcp_qdio_sbals_from_sg(struct zfcp_fsf_req *, unsigned long,
                                   struct scatterlist *, int);
 extern int zfcp_qdio_open(struct zfcp_adapter *);
@@ -148,14 +151,12 @@ extern void zfcp_qdio_close(struct zfcp_adapter *);
 extern struct zfcp_data zfcp_data;
 extern int zfcp_adapter_scsi_register(struct zfcp_adapter *);
 extern void zfcp_adapter_scsi_unregister(struct zfcp_adapter *);
-extern void zfcp_set_fcp_dl(struct fcp_cmnd_iu *, fcp_dl_t);
 extern char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *);
 extern struct fc_function_template zfcp_transport_functions;
 
 /* zfcp_sysfs.c */
 extern struct attribute_group zfcp_sysfs_unit_attrs;
 extern struct attribute_group zfcp_sysfs_adapter_attrs;
-extern struct attribute_group zfcp_sysfs_ns_port_attrs;
 extern struct attribute_group zfcp_sysfs_port_attrs;
 extern struct device_attribute *zfcp_sysfs_sdev_attrs[];
 extern struct device_attribute *zfcp_sysfs_shost_attrs[];
index 56196c98c07b417f060e44dfb6c8a2dce2543e89..1a7c80a77ff582cf90ed2cf3677a88a50c7ca4a3 100644 (file)
@@ -39,6 +39,84 @@ struct zfcp_gpn_ft {
        struct scatterlist sg_resp[ZFCP_GPN_FT_BUFFERS];
 };
 
+struct zfcp_fc_ns_handler_data {
+       struct completion done;
+       void (*handler)(unsigned long);
+       unsigned long handler_data;
+};
+
+static int zfcp_wka_port_get(struct zfcp_wka_port *wka_port)
+{
+       if (mutex_lock_interruptible(&wka_port->mutex))
+               return -ERESTARTSYS;
+
+       if (wka_port->status != ZFCP_WKA_PORT_ONLINE) {
+               wka_port->status = ZFCP_WKA_PORT_OPENING;
+               if (zfcp_fsf_open_wka_port(wka_port))
+                       wka_port->status = ZFCP_WKA_PORT_OFFLINE;
+       }
+
+       mutex_unlock(&wka_port->mutex);
+
+       wait_event_timeout(
+               wka_port->completion_wq,
+               wka_port->status == ZFCP_WKA_PORT_ONLINE ||
+               wka_port->status == ZFCP_WKA_PORT_OFFLINE,
+               HZ >> 1);
+
+       if (wka_port->status == ZFCP_WKA_PORT_ONLINE) {
+               atomic_inc(&wka_port->refcount);
+               return 0;
+       }
+       return -EIO;
+}
+
+static void zfcp_wka_port_offline(struct work_struct *work)
+{
+       struct delayed_work *dw = container_of(work, struct delayed_work, work);
+       struct zfcp_wka_port *wka_port =
+                       container_of(dw, struct zfcp_wka_port, work);
+
+       wait_event(wka_port->completion_wq,
+                       atomic_read(&wka_port->refcount) == 0);
+
+       mutex_lock(&wka_port->mutex);
+       if ((atomic_read(&wka_port->refcount) != 0) ||
+           (wka_port->status != ZFCP_WKA_PORT_ONLINE))
+               goto out;
+
+       wka_port->status = ZFCP_WKA_PORT_CLOSING;
+       if (zfcp_fsf_close_wka_port(wka_port)) {
+               wka_port->status = ZFCP_WKA_PORT_OFFLINE;
+               wake_up(&wka_port->completion_wq);
+       }
+out:
+       mutex_unlock(&wka_port->mutex);
+}
+
+static void zfcp_wka_port_put(struct zfcp_wka_port *wka_port)
+{
+       if (atomic_dec_return(&wka_port->refcount) != 0)
+               return;
+       /* wait 10 miliseconds, other reqs might pop in */
+       schedule_delayed_work(&wka_port->work, HZ / 100);
+}
+
+void zfcp_fc_nameserver_init(struct zfcp_adapter *adapter)
+{
+       struct zfcp_wka_port *wka_port = &adapter->nsp;
+
+       init_waitqueue_head(&wka_port->completion_wq);
+
+       wka_port->adapter = adapter;
+       wka_port->d_id = ZFCP_DID_DIRECTORY_SERVICE;
+
+       wka_port->status = ZFCP_WKA_PORT_OFFLINE;
+       atomic_set(&wka_port->refcount, 0);
+       mutex_init(&wka_port->mutex);
+       INIT_DELAYED_WORK(&wka_port->work, zfcp_wka_port_offline);
+}
+
 static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range,
                                   struct fcp_rscn_element *elem)
 {
@@ -47,10 +125,8 @@ static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range,
 
        read_lock_irqsave(&zfcp_data.config_lock, flags);
        list_for_each_entry(port, &fsf_req->adapter->port_list_head, list) {
-               if (atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status))
-                       continue;
                /* FIXME: ZFCP_STATUS_PORT_DID_DID check is racy */
-               if (!atomic_test_mask(ZFCP_STATUS_PORT_DID_DID, &port->status))
+               if (!(atomic_read(&port->status) & ZFCP_STATUS_PORT_DID_DID))
                        /* Try to connect to unused ports anyway. */
                        zfcp_erp_port_reopen(port,
                                             ZFCP_STATUS_COMMON_ERP_FAILED,
@@ -102,7 +178,7 @@ static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req)
        schedule_work(&fsf_req->adapter->scan_work);
 }
 
-static void zfcp_fc_incoming_wwpn(struct zfcp_fsf_req *req, wwn_t wwpn)
+static void zfcp_fc_incoming_wwpn(struct zfcp_fsf_req *req, u64 wwpn)
 {
        struct zfcp_adapter *adapter = req->adapter;
        struct zfcp_port *port;
@@ -157,7 +233,18 @@ void zfcp_fc_incoming_els(struct zfcp_fsf_req *fsf_req)
                zfcp_fc_incoming_rscn(fsf_req);
 }
 
-static void zfcp_ns_gid_pn_handler(unsigned long data)
+static void zfcp_fc_ns_handler(unsigned long data)
+{
+       struct zfcp_fc_ns_handler_data *compl_rec =
+                       (struct zfcp_fc_ns_handler_data *) data;
+
+       if (compl_rec->handler)
+               compl_rec->handler(compl_rec->handler_data);
+
+       complete(&compl_rec->done);
+}
+
+static void zfcp_fc_ns_gid_pn_eval(unsigned long data)
 {
        struct zfcp_gid_pn_data *gid_pn = (struct zfcp_gid_pn_data *) data;
        struct zfcp_send_ct *ct = &gid_pn->ct;
@@ -166,43 +253,31 @@ static void zfcp_ns_gid_pn_handler(unsigned long data)
        struct zfcp_port *port = gid_pn->port;
 
        if (ct->status)
-               goto out;
+               return;
        if (ct_iu_resp->header.cmd_rsp_code != ZFCP_CT_ACCEPT) {
                atomic_set_mask(ZFCP_STATUS_PORT_INVALID_WWPN, &port->status);
-               goto out;
+               return;
        }
        /* paranoia */
        if (ct_iu_req->wwpn != port->wwpn)
-               goto out;
+               return;
        /* looks like a valid d_id */
        port->d_id = ct_iu_resp->d_id & ZFCP_DID_MASK;
        atomic_set_mask(ZFCP_STATUS_PORT_DID_DID, &port->status);
-out:
-       mempool_free(gid_pn, port->adapter->pool.data_gid_pn);
 }
 
-/**
- * zfcp_fc_ns_gid_pn_request - initiate GID_PN nameserver request
- * @erp_action: pointer to zfcp_erp_action where GID_PN request is needed
- * return: -ENOMEM on error, 0 otherwise
- */
-int zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action)
+int static zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action,
+                                    struct zfcp_gid_pn_data *gid_pn)
 {
-       int ret;
-       struct zfcp_gid_pn_data *gid_pn;
        struct zfcp_adapter *adapter = erp_action->adapter;
-
-       gid_pn = mempool_alloc(adapter->pool.data_gid_pn, GFP_ATOMIC);
-       if (!gid_pn)
-               return -ENOMEM;
-
-       memset(gid_pn, 0, sizeof(*gid_pn));
+       struct zfcp_fc_ns_handler_data compl_rec;
+       int ret;
 
        /* setup parameters for send generic command */
        gid_pn->port = erp_action->port;
-       gid_pn->ct.port = adapter->nameserver_port;
-       gid_pn->ct.handler = zfcp_ns_gid_pn_handler;
-       gid_pn->ct.handler_data = (unsigned long) gid_pn;
+       gid_pn->ct.wka_port = &adapter->nsp;
+       gid_pn->ct.handler = zfcp_fc_ns_handler;
+       gid_pn->ct.handler_data = (unsigned long) &compl_rec;
        gid_pn->ct.timeout = ZFCP_NS_GID_PN_TIMEOUT;
        gid_pn->ct.req = &gid_pn->req;
        gid_pn->ct.resp = &gid_pn->resp;
@@ -222,10 +297,42 @@ int zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action)
        gid_pn->ct_iu_req.header.max_res_size = ZFCP_CT_MAX_SIZE;
        gid_pn->ct_iu_req.wwpn = erp_action->port->wwpn;
 
+       init_completion(&compl_rec.done);
+       compl_rec.handler = zfcp_fc_ns_gid_pn_eval;
+       compl_rec.handler_data = (unsigned long) gid_pn;
        ret = zfcp_fsf_send_ct(&gid_pn->ct, adapter->pool.fsf_req_erp,
                               erp_action);
+       if (!ret)
+               wait_for_completion(&compl_rec.done);
+       return ret;
+}
+
+/**
+ * zfcp_fc_ns_gid_pn_request - initiate GID_PN nameserver request
+ * @erp_action: pointer to zfcp_erp_action where GID_PN request is needed
+ * return: -ENOMEM on error, 0 otherwise
+ */
+int zfcp_fc_ns_gid_pn(struct zfcp_erp_action *erp_action)
+{
+       int ret;
+       struct zfcp_gid_pn_data *gid_pn;
+       struct zfcp_adapter *adapter = erp_action->adapter;
+
+       gid_pn = mempool_alloc(adapter->pool.data_gid_pn, GFP_ATOMIC);
+       if (!gid_pn)
+               return -ENOMEM;
+
+       memset(gid_pn, 0, sizeof(*gid_pn));
+
+       ret = zfcp_wka_port_get(&adapter->nsp);
        if (ret)
-               mempool_free(gid_pn, adapter->pool.data_gid_pn);
+               goto out;
+
+       ret = zfcp_fc_ns_gid_pn_request(erp_action, gid_pn);
+
+       zfcp_wka_port_put(&adapter->nsp);
+out:
+       mempool_free(gid_pn, adapter->pool.data_gid_pn);
        return ret;
 }
 
@@ -255,14 +362,14 @@ struct zfcp_els_adisc {
        struct scatterlist req;
        struct scatterlist resp;
        struct zfcp_ls_adisc ls_adisc;
-       struct zfcp_ls_adisc_acc ls_adisc_acc;
+       struct zfcp_ls_adisc ls_adisc_acc;
 };
 
 static void zfcp_fc_adisc_handler(unsigned long data)
 {
        struct zfcp_els_adisc *adisc = (struct zfcp_els_adisc *) data;
        struct zfcp_port *port = adisc->els.port;
-       struct zfcp_ls_adisc_acc *ls_adisc = &adisc->ls_adisc_acc;
+       struct zfcp_ls_adisc *ls_adisc = &adisc->ls_adisc_acc;
 
        if (adisc->els.status) {
                /* request rejected or timed out */
@@ -295,7 +402,7 @@ static int zfcp_fc_adisc(struct zfcp_port *port)
        sg_init_one(adisc->els.req, &adisc->ls_adisc,
                    sizeof(struct zfcp_ls_adisc));
        sg_init_one(adisc->els.resp, &adisc->ls_adisc_acc,
-                   sizeof(struct zfcp_ls_adisc_acc));
+                   sizeof(struct zfcp_ls_adisc));
 
        adisc->els.req_count = 1;
        adisc->els.resp_count = 1;
@@ -338,30 +445,6 @@ void zfcp_test_link(struct zfcp_port *port)
                zfcp_erp_port_forced_reopen(port, 0, 65, NULL);
 }
 
-static int zfcp_scan_get_nameserver(struct zfcp_adapter *adapter)
-{
-       int ret;
-
-       if (!adapter->nameserver_port)
-               return -EINTR;
-
-       if (!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED,
-                              &adapter->nameserver_port->status)) {
-               ret = zfcp_erp_port_reopen(adapter->nameserver_port, 0, 148,
-                                          NULL);
-               if (ret)
-                       return ret;
-               zfcp_erp_wait(adapter);
-       }
-       return !atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED,
-                                 &adapter->nameserver_port->status);
-}
-
-static void zfcp_gpn_ft_handler(unsigned long _done)
-{
-       complete((struct completion *)_done);
-}
-
 static void zfcp_free_sg_env(struct zfcp_gpn_ft *gpn_ft)
 {
        struct scatterlist *sg = &gpn_ft->sg_req;
@@ -403,7 +486,7 @@ static int zfcp_scan_issue_gpn_ft(struct zfcp_gpn_ft *gpn_ft,
 {
        struct zfcp_send_ct *ct = &gpn_ft->ct;
        struct ct_iu_gpn_ft_req *req = sg_virt(&gpn_ft->sg_req);
-       struct completion done;
+       struct zfcp_fc_ns_handler_data compl_rec;
        int ret;
 
        /* prepare CT IU for GPN_FT */
@@ -420,19 +503,20 @@ static int zfcp_scan_issue_gpn_ft(struct zfcp_gpn_ft *gpn_ft,
        req->fc4_type = ZFCP_CT_SCSI_FCP;
 
        /* prepare zfcp_send_ct */
-       ct->port = adapter->nameserver_port;
-       ct->handler = zfcp_gpn_ft_handler;
-       ct->handler_data = (unsigned long)&done;
+       ct->wka_port = &adapter->nsp;
+       ct->handler = zfcp_fc_ns_handler;
+       ct->handler_data = (unsigned long)&compl_rec;
        ct->timeout = 10;
        ct->req = &gpn_ft->sg_req;
        ct->resp = gpn_ft->sg_resp;
        ct->req_count = 1;
        ct->resp_count = ZFCP_GPN_FT_BUFFERS;
 
-       init_completion(&done);
+       init_completion(&compl_rec.done);
+       compl_rec.handler = NULL;
        ret = zfcp_fsf_send_ct(ct, NULL, NULL);
        if (!ret)
-               wait_for_completion(&done);
+               wait_for_completion(&compl_rec.done);
        return ret;
 }
 
@@ -442,9 +526,8 @@ static void zfcp_validate_port(struct zfcp_port *port)
 
        atomic_clear_mask(ZFCP_STATUS_COMMON_NOESC, &port->status);
 
-       if (port == adapter->nameserver_port)
-               return;
-       if ((port->supported_classes != 0) || (port->units != 0)) {
+       if ((port->supported_classes != 0) ||
+           !list_empty(&port->unit_list_head)) {
                zfcp_port_put(port);
                return;
        }
@@ -460,7 +543,7 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft)
        struct scatterlist *sg = gpn_ft->sg_resp;
        struct ct_hdr *hdr = sg_virt(sg);
        struct gpn_ft_resp_acc *acc = sg_virt(sg);
-       struct zfcp_adapter *adapter = ct->port->adapter;
+       struct zfcp_adapter *adapter = ct->wka_port->adapter;
        struct zfcp_port *port, *tmp;
        u32 d_id;
        int ret = 0, x, last = 0;
@@ -490,6 +573,9 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft)
                d_id = acc->port_id[0] << 16 | acc->port_id[1] << 8 |
                       acc->port_id[2];
 
+               /* don't attach ports with a well known address */
+               if ((d_id & ZFCP_DID_WKA) == ZFCP_DID_WKA)
+                       continue;
                /* skip the adapter's port and known remote ports */
                if (acc->wwpn == fc_host_port_name(adapter->scsi_host))
                        continue;
@@ -528,13 +614,15 @@ int zfcp_scan_ports(struct zfcp_adapter *adapter)
        if (fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPORT)
                return 0;
 
-       ret = zfcp_scan_get_nameserver(adapter);
+       ret = zfcp_wka_port_get(&adapter->nsp);
        if (ret)
                return ret;
 
        gpn_ft = zfcp_alloc_sg_env();
-       if (!gpn_ft)
-               return -ENOMEM;
+       if (!gpn_ft) {
+               ret = -ENOMEM;
+               goto out;
+       }
 
        for (i = 0; i < 3; i++) {
                ret = zfcp_scan_issue_gpn_ft(gpn_ft, adapter);
@@ -547,7 +635,8 @@ int zfcp_scan_ports(struct zfcp_adapter *adapter)
                }
        }
        zfcp_free_sg_env(gpn_ft);
-
+out:
+       zfcp_wka_port_put(&adapter->nsp);
        return ret;
 }
 
index 49dbeb754e5f30b5c732200adfcff8b368b9d442..739356a5c123f9310c944739c584e0eb9604cace 100644 (file)
@@ -50,19 +50,16 @@ static u32 fsf_qtcb_type[] = {
        [FSF_QTCB_UPLOAD_CONTROL_FILE] =  FSF_SUPPORT_COMMAND
 };
 
-static const char *zfcp_act_subtable_type[] = {
-       "unknown", "OS", "WWPN", "DID", "LUN"
-};
-
 static void zfcp_act_eval_err(struct zfcp_adapter *adapter, u32 table)
 {
        u16 subtable = table >> 16;
        u16 rule = table & 0xffff;
+       const char *act_type[] = { "unknown", "OS", "WWPN", "DID", "LUN" };
 
-       if (subtable && subtable < ARRAY_SIZE(zfcp_act_subtable_type))
+       if (subtable && subtable < ARRAY_SIZE(act_type))
                dev_warn(&adapter->ccw_device->dev,
-                        "Access denied in subtable %s, rule %d.\n",
-                        zfcp_act_subtable_type[subtable], rule);
+                        "Access denied according to ACT rule type %s, "
+                        "rule %d\n", act_type[subtable], rule);
 }
 
 static void zfcp_fsf_access_denied_port(struct zfcp_fsf_req *req,
@@ -70,8 +67,8 @@ static void zfcp_fsf_access_denied_port(struct zfcp_fsf_req *req,
 {
        struct fsf_qtcb_header *header = &req->qtcb->header;
        dev_warn(&req->adapter->ccw_device->dev,
-                "Access denied, cannot send command to port 0x%016Lx.\n",
-                port->wwpn);
+                "Access denied to port 0x%016Lx\n",
+                (unsigned long long)port->wwpn);
        zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[0]);
        zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[1]);
        zfcp_erp_port_access_denied(port, 55, req);
@@ -83,8 +80,9 @@ static void zfcp_fsf_access_denied_unit(struct zfcp_fsf_req *req,
 {
        struct fsf_qtcb_header *header = &req->qtcb->header;
        dev_warn(&req->adapter->ccw_device->dev,
-                "Access denied for unit 0x%016Lx on port 0x%016Lx.\n",
-                unit->fcp_lun, unit->port->wwpn);
+                "Access denied to unit 0x%016Lx on port 0x%016Lx\n",
+                (unsigned long long)unit->fcp_lun,
+                (unsigned long long)unit->port->wwpn);
        zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[0]);
        zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[1]);
        zfcp_erp_unit_access_denied(unit, 59, req);
@@ -93,9 +91,8 @@ static void zfcp_fsf_access_denied_unit(struct zfcp_fsf_req *req,
 
 static void zfcp_fsf_class_not_supp(struct zfcp_fsf_req *req)
 {
-       dev_err(&req->adapter->ccw_device->dev,
-               "Required FC class not supported by adapter, "
-               "shutting down adapter.\n");
+       dev_err(&req->adapter->ccw_device->dev, "FCP device not "
+               "operational because of an unsupported FC class\n");
        zfcp_erp_adapter_shutdown(req->adapter, 0, 123, req);
        req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 }
@@ -171,42 +168,6 @@ static void zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *req)
        read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 }
 
-static void zfcp_fsf_bit_error_threshold(struct zfcp_fsf_req *req)
-{
-       struct zfcp_adapter *adapter = req->adapter;
-       struct fsf_status_read_buffer *sr_buf = req->data;
-       struct fsf_bit_error_payload *err = &sr_buf->payload.bit_error;
-
-       dev_warn(&adapter->ccw_device->dev,
-                "Warning: bit error threshold data "
-                "received for the adapter: "
-                "link failures = %i, loss of sync errors = %i, "
-                "loss of signal errors = %i, "
-                "primitive sequence errors = %i, "
-                "invalid transmission word errors = %i, "
-                "CRC errors = %i).\n",
-                err->link_failure_error_count,
-                err->loss_of_sync_error_count,
-                err->loss_of_signal_error_count,
-                err->primitive_sequence_error_count,
-                err->invalid_transmission_word_error_count,
-                err->crc_error_count);
-       dev_warn(&adapter->ccw_device->dev,
-                "Additional bit error threshold data of the adapter: "
-                "primitive sequence event time-outs = %i, "
-                "elastic buffer overrun errors = %i, "
-                "advertised receive buffer-to-buffer credit = %i, "
-                "current receice buffer-to-buffer credit = %i, "
-                "advertised transmit buffer-to-buffer credit = %i, "
-                "current transmit buffer-to-buffer credit = %i).\n",
-                err->primitive_sequence_event_timeout_count,
-                err->elastic_buffer_overrun_error_count,
-                err->advertised_receive_b2b_credit,
-                err->current_receive_b2b_credit,
-                err->advertised_transmit_b2b_credit,
-                err->current_transmit_b2b_credit);
-}
-
 static void zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *req, u8 id,
                                         struct fsf_link_down_info *link_down)
 {
@@ -223,62 +184,66 @@ static void zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *req, u8 id,
        switch (link_down->error_code) {
        case FSF_PSQ_LINK_NO_LIGHT:
                dev_warn(&req->adapter->ccw_device->dev,
-                        "The local link is down: no light detected.\n");
+                        "There is no light signal from the local "
+                        "fibre channel cable\n");
                break;
        case FSF_PSQ_LINK_WRAP_PLUG:
                dev_warn(&req->adapter->ccw_device->dev,
-                        "The local link is down: wrap plug detected.\n");
+                        "There is a wrap plug instead of a fibre "
+                        "channel cable\n");
                break;
        case FSF_PSQ_LINK_NO_FCP:
                dev_warn(&req->adapter->ccw_device->dev,
-                        "The local link is down: "
-                        "adjacent node on link does not support FCP.\n");
+                        "The adjacent fibre channel node does not "
+                        "support FCP\n");
                break;
        case FSF_PSQ_LINK_FIRMWARE_UPDATE:
                dev_warn(&req->adapter->ccw_device->dev,
-                        "The local link is down: "
-                        "firmware update in progress.\n");
+                        "The FCP device is suspended because of a "
+                        "firmware update\n");
                break;
        case FSF_PSQ_LINK_INVALID_WWPN:
                dev_warn(&req->adapter->ccw_device->dev,
-                        "The local link is down: "
-                        "duplicate or invalid WWPN detected.\n");
+                        "The FCP device detected a WWPN that is "
+                        "duplicate or not valid\n");
                break;
        case FSF_PSQ_LINK_NO_NPIV_SUPPORT:
                dev_warn(&req->adapter->ccw_device->dev,
-                        "The local link is down: "
-                        "no support for NPIV by Fabric.\n");
+                        "The fibre channel fabric does not support NPIV\n");
                break;
        case FSF_PSQ_LINK_NO_FCP_RESOURCES:
                dev_warn(&req->adapter->ccw_device->dev,
-                        "The local link is down: "
-                        "out of resource in FCP daughtercard.\n");
+                        "The FCP adapter cannot support more NPIV ports\n");
                break;
        case FSF_PSQ_LINK_NO_FABRIC_RESOURCES:
                dev_warn(&req->adapter->ccw_device->dev,
-                        "The local link is down: "
-                        "out of resource in Fabric.\n");
+                        "The adjacent switch cannot support "
+                        "more NPIV ports\n");
                break;
        case FSF_PSQ_LINK_FABRIC_LOGIN_UNABLE:
                dev_warn(&req->adapter->ccw_device->dev,
-                        "The local link is down: "
-                        "unable to login to Fabric.\n");
+                        "The FCP adapter could not log in to the "
+                        "fibre channel fabric\n");
                break;
        case FSF_PSQ_LINK_WWPN_ASSIGNMENT_CORRUPTED:
                dev_warn(&req->adapter->ccw_device->dev,
-                        "WWPN assignment file corrupted on adapter.\n");
+                        "The WWPN assignment file on the FCP adapter "
+                        "has been damaged\n");
                break;
        case FSF_PSQ_LINK_MODE_TABLE_CURRUPTED:
                dev_warn(&req->adapter->ccw_device->dev,
-                        "Mode table corrupted on adapter.\n");
+                        "The mode table on the FCP adapter "
+                        "has been damaged\n");
                break;
        case FSF_PSQ_LINK_NO_WWPN_ASSIGNMENT:
                dev_warn(&req->adapter->ccw_device->dev,
-                        "No WWPN for assignment table on adapter.\n");
+                        "All NPIV ports on the FCP adapter have "
+                        "been assigned\n");
                break;
        default:
                dev_warn(&req->adapter->ccw_device->dev,
-                        "The local link to adapter is down.\n");
+                        "The link between the FCP adapter and "
+                        "the FC fabric is down\n");
        }
 out:
        zfcp_erp_adapter_failed(adapter, id, req);
@@ -286,27 +251,18 @@ out:
 
 static void zfcp_fsf_status_read_link_down(struct zfcp_fsf_req *req)
 {
-       struct zfcp_adapter *adapter = req->adapter;
        struct fsf_status_read_buffer *sr_buf = req->data;
        struct fsf_link_down_info *ldi =
                (struct fsf_link_down_info *) &sr_buf->payload;
 
        switch (sr_buf->status_subtype) {
        case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK:
-               dev_warn(&adapter->ccw_device->dev,
-                        "Physical link is down.\n");
                zfcp_fsf_link_down_info_eval(req, 38, ldi);
                break;
        case FSF_STATUS_READ_SUB_FDISC_FAILED:
-               dev_warn(&adapter->ccw_device->dev,
-                        "Local link is down "
-                        "due to failed FDISC login.\n");
                zfcp_fsf_link_down_info_eval(req, 39, ldi);
                break;
        case FSF_STATUS_READ_SUB_FIRMWARE_UPDATE:
-               dev_warn(&adapter->ccw_device->dev,
-                        "Local link is down "
-                        "due to firmware update on adapter.\n");
                zfcp_fsf_link_down_info_eval(req, 40, NULL);
        };
 }
@@ -335,14 +291,17 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req)
        case FSF_STATUS_READ_SENSE_DATA_AVAIL:
                break;
        case FSF_STATUS_READ_BIT_ERROR_THRESHOLD:
-               zfcp_fsf_bit_error_threshold(req);
+               dev_warn(&adapter->ccw_device->dev,
+                        "The error threshold for checksum statistics "
+                        "has been exceeded\n");
+               zfcp_hba_dbf_event_berr(adapter, req);
                break;
        case FSF_STATUS_READ_LINK_DOWN:
                zfcp_fsf_status_read_link_down(req);
                break;
        case FSF_STATUS_READ_LINK_UP:
                dev_info(&adapter->ccw_device->dev,
-                        "Local link was replugged.\n");
+                        "The local link has been restored\n");
                /* All ports should be marked as ready to run again */
                zfcp_erp_modify_adapter_status(adapter, 30, NULL,
                                               ZFCP_STATUS_COMMON_RUNNING,
@@ -370,7 +329,7 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req)
        zfcp_fsf_req_free(req);
 
        atomic_inc(&adapter->stat_miss);
-       schedule_work(&adapter->stat_work);
+       queue_work(zfcp_data.work_queue, &adapter->stat_work);
 }
 
 static void zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *req)
@@ -386,8 +345,8 @@ static void zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *req)
                break;
        case FSF_SQ_NO_RECOM:
                dev_err(&req->adapter->ccw_device->dev,
-                       "No recommendation could be given for a "
-                       "problem on the adapter.\n");
+                       "The FCP adapter reported a problem "
+                       "that cannot be recovered\n");
                zfcp_erp_adapter_shutdown(req->adapter, 0, 121, req);
                break;
        }
@@ -403,8 +362,7 @@ static void zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_req *req)
        switch (req->qtcb->header.fsf_status) {
        case FSF_UNKNOWN_COMMAND:
                dev_err(&req->adapter->ccw_device->dev,
-                       "Command issued by the device driver (0x%x) is "
-                       "not known by the adapter.\n",
+                       "The FCP adapter does not recognize the command 0x%x\n",
                        req->qtcb->header.fsf_command);
                zfcp_erp_adapter_shutdown(req->adapter, 0, 120, req);
                req->status |= ZFCP_STATUS_FSFREQ_ERROR;
@@ -435,11 +393,9 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req)
                return;
        case FSF_PROT_QTCB_VERSION_ERROR:
                dev_err(&adapter->ccw_device->dev,
-                       "The QTCB version requested by zfcp (0x%x) is not "
-                       "supported by the FCP adapter (lowest supported "
-                       "0x%x, highest supported 0x%x).\n",
-                       FSF_QTCB_CURRENT_VERSION, psq->word[0],
-                       psq->word[1]);
+                       "QTCB version 0x%x not supported by FCP adapter "
+                       "(0x%x to 0x%x)\n", FSF_QTCB_CURRENT_VERSION,
+                       psq->word[0], psq->word[1]);
                zfcp_erp_adapter_shutdown(adapter, 0, 117, req);
                break;
        case FSF_PROT_ERROR_STATE:
@@ -449,8 +405,7 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req)
                break;
        case FSF_PROT_UNSUPP_QTCB_TYPE:
                dev_err(&adapter->ccw_device->dev,
-                       "Packet header type used by the device driver is "
-                       "incompatible with that used on the adapter.\n");
+                       "The QTCB type is not supported by the FCP adapter\n");
                zfcp_erp_adapter_shutdown(adapter, 0, 118, req);
                break;
        case FSF_PROT_HOST_CONNECTION_INITIALIZING:
@@ -459,7 +414,7 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req)
                break;
        case FSF_PROT_DUPLICATE_REQUEST_ID:
                dev_err(&adapter->ccw_device->dev,
-                       "The request identifier 0x%Lx is ambiguous.\n",
+                       "0x%Lx is an ambiguous request identifier\n",
                        (unsigned long long)qtcb->bottom.support.req_handle);
                zfcp_erp_adapter_shutdown(adapter, 0, 78, req);
                break;
@@ -479,9 +434,7 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req)
                break;
        default:
                dev_err(&adapter->ccw_device->dev,
-                       "Transfer protocol status information"
-                       "provided by the adapter (0x%x) "
-                       "is not compatible with the device driver.\n",
+                       "0x%x is not a valid transfer protocol status\n",
                        qtcb->prefix.prot_status);
                zfcp_erp_adapter_shutdown(adapter, 0, 119, req);
        }
@@ -559,33 +512,17 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req)
                adapter->peer_wwpn = bottom->plogi_payload.wwpn;
                adapter->peer_wwnn = bottom->plogi_payload.wwnn;
                fc_host_port_type(shost) = FC_PORTTYPE_PTP;
-               if (req->erp_action)
-                       dev_info(&adapter->ccw_device->dev,
-                                "Point-to-Point fibrechannel "
-                                "configuration detected.\n");
                break;
        case FSF_TOPO_FABRIC:
                fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
-               if (req->erp_action)
-                       dev_info(&adapter->ccw_device->dev,
-                                "Switched fabric fibrechannel "
-                                "network detected.\n");
                break;
        case FSF_TOPO_AL:
                fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
-               dev_err(&adapter->ccw_device->dev,
-                       "Unsupported arbitrated loop fibrechannel "
-                       "topology detected, shutting down "
-                       "adapter.\n");
-               zfcp_erp_adapter_shutdown(adapter, 0, 127, req);
-               return -EIO;
        default:
-               fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
                dev_err(&adapter->ccw_device->dev,
-                       "The fibrechannel topology reported by the"
-                       " adapter is not known by the zfcp driver,"
-                       " shutting down adapter.\n");
-               zfcp_erp_adapter_shutdown(adapter, 0, 128, req);
+                       "Unknown or unsupported arbitrated loop "
+                       "fibre channel topology detected\n");
+               zfcp_erp_adapter_shutdown(adapter, 0, 127, req);
                return -EIO;
        }
 
@@ -616,11 +553,9 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req)
 
                if (bottom->max_qtcb_size < sizeof(struct fsf_qtcb)) {
                        dev_err(&adapter->ccw_device->dev,
-                               "Maximum QTCB size (%d bytes) allowed by "
-                               "the adapter is lower than the minimum "
-                               "required by the driver (%ld bytes).\n",
-                               bottom->max_qtcb_size,
-                               sizeof(struct fsf_qtcb));
+                               "FCP adapter maximum QTCB size (%d bytes) "
+                               "is too small\n",
+                               bottom->max_qtcb_size);
                        zfcp_erp_adapter_shutdown(adapter, 0, 129, req);
                        return;
                }
@@ -656,15 +591,15 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req)
 
        if (FSF_QTCB_CURRENT_VERSION < bottom->low_qtcb_version) {
                dev_err(&adapter->ccw_device->dev,
-                       "The adapter only supports newer control block "
-                       "versions, try updated device driver.\n");
+                       "The FCP adapter only supports newer "
+                       "control block versions\n");
                zfcp_erp_adapter_shutdown(adapter, 0, 125, req);
                return;
        }
        if (FSF_QTCB_CURRENT_VERSION > bottom->high_qtcb_version) {
                dev_err(&adapter->ccw_device->dev,
-                       "The adapter only supports older control block "
-                       "versions, consider a microcode upgrade.\n");
+                       "The FCP adapter only supports older "
+                       "control block versions\n");
                zfcp_erp_adapter_shutdown(adapter, 0, 126, req);
        }
 }
@@ -688,7 +623,6 @@ static void zfcp_fsf_exchange_port_evaluate(struct zfcp_fsf_req *req)
 
 static void zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *req)
 {
-       struct zfcp_adapter *adapter = req->adapter;
        struct fsf_qtcb *qtcb = req->qtcb;
 
        if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
@@ -697,38 +631,47 @@ static void zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *req)
        switch (qtcb->header.fsf_status) {
        case FSF_GOOD:
                zfcp_fsf_exchange_port_evaluate(req);
-               atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status);
                break;
        case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE:
                zfcp_fsf_exchange_port_evaluate(req);
-               atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status);
                zfcp_fsf_link_down_info_eval(req, 43,
                        &qtcb->header.fsf_status_qual.link_down_info);
                break;
        }
 }
 
-static int zfcp_fsf_sbal_check(struct zfcp_qdio_queue *queue)
+static int zfcp_fsf_sbal_check(struct zfcp_adapter *adapter)
 {
-       spin_lock_bh(&queue->lock);
-       if (atomic_read(&queue->count))
+       struct zfcp_qdio_queue *req_q = &adapter->req_q;
+
+       spin_lock_bh(&adapter->req_q_lock);
+       if (atomic_read(&req_q->count))
                return 1;
-       spin_unlock_bh(&queue->lock);
+       spin_unlock_bh(&adapter->req_q_lock);
        return 0;
 }
 
+static int zfcp_fsf_sbal_available(struct zfcp_adapter *adapter)
+{
+       unsigned int count = atomic_read(&adapter->req_q.count);
+       if (!count)
+               atomic_inc(&adapter->qdio_outb_full);
+       return count > 0;
+}
+
 static int zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter)
 {
        long ret;
-       struct zfcp_qdio_queue *req_q = &adapter->req_q;
 
-       spin_unlock_bh(&req_q->lock);
+       spin_unlock_bh(&adapter->req_q_lock);
        ret = wait_event_interruptible_timeout(adapter->request_wq,
-                                       zfcp_fsf_sbal_check(req_q), 5 * HZ);
+                                       zfcp_fsf_sbal_check(adapter), 5 * HZ);
        if (ret > 0)
                return 0;
+       if (!ret)
+               atomic_inc(&adapter->qdio_outb_full);
 
-       spin_lock_bh(&req_q->lock);
+       spin_lock_bh(&adapter->req_q_lock);
        return -EIO;
 }
 
@@ -765,7 +708,7 @@ static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_adapter *adapter,
                                                u32 fsf_cmd, int req_flags,
                                                mempool_t *pool)
 {
-       volatile struct qdio_buffer_element *sbale;
+       struct qdio_buffer_element *sbale;
 
        struct zfcp_fsf_req *req;
        struct zfcp_qdio_queue *req_q = &adapter->req_q;
@@ -867,10 +810,10 @@ int zfcp_fsf_status_read(struct zfcp_adapter *adapter)
 {
        struct zfcp_fsf_req *req;
        struct fsf_status_read_buffer *sr_buf;
-       volatile struct qdio_buffer_element *sbale;
+       struct qdio_buffer_element *sbale;
        int retval = -EIO;
 
-       spin_lock_bh(&adapter->req_q.lock);
+       spin_lock_bh(&adapter->req_q_lock);
        if (zfcp_fsf_req_sbal_get(adapter))
                goto out;
 
@@ -910,7 +853,7 @@ failed_buf:
        zfcp_fsf_req_free(req);
        zfcp_hba_dbf_event_fsf_unsol("fail", adapter, NULL);
 out:
-       spin_unlock_bh(&adapter->req_q.lock);
+       spin_unlock_bh(&adapter->req_q_lock);
        return retval;
 }
 
@@ -980,11 +923,11 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long old_req_id,
                                                struct zfcp_unit *unit,
                                                int req_flags)
 {
-       volatile struct qdio_buffer_element *sbale;
+       struct qdio_buffer_element *sbale;
        struct zfcp_fsf_req *req = NULL;
 
-       spin_lock(&adapter->req_q.lock);
-       if (!atomic_read(&adapter->req_q.count))
+       spin_lock(&adapter->req_q_lock);
+       if (!zfcp_fsf_sbal_available(adapter))
                goto out;
        req = zfcp_fsf_req_create(adapter, FSF_QTCB_ABORT_FCP_CMND,
                                  req_flags, adapter->pool.fsf_req_abort);
@@ -1013,7 +956,7 @@ out_error_free:
        zfcp_fsf_req_free(req);
        req = NULL;
 out:
-       spin_unlock(&adapter->req_q.lock);
+       spin_unlock(&adapter->req_q_lock);
        return req;
 }
 
@@ -1021,7 +964,6 @@ static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req)
 {
        struct zfcp_adapter *adapter = req->adapter;
        struct zfcp_send_ct *send_ct = req->data;
-       struct zfcp_port *port = send_ct->port;
        struct fsf_qtcb_header *header = &req->qtcb->header;
 
        send_ct->status = -EINVAL;
@@ -1040,17 +982,14 @@ static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req)
         case FSF_ADAPTER_STATUS_AVAILABLE:
                 switch (header->fsf_status_qual.word[0]){
                 case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
-                       zfcp_test_link(port);
                 case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
                        req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                        break;
                 }
                 break;
        case FSF_ACCESS_DENIED:
-               zfcp_fsf_access_denied_port(req, port);
                break;
         case FSF_PORT_BOXED:
-               zfcp_erp_port_boxed(port, 49, req);
                req->status |= ZFCP_STATUS_FSFREQ_ERROR |
                               ZFCP_STATUS_FSFREQ_RETRY;
                break;
@@ -1101,12 +1040,12 @@ static int zfcp_fsf_setup_sbals(struct zfcp_fsf_req *req,
 int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool,
                     struct zfcp_erp_action *erp_action)
 {
-       struct zfcp_port *port = ct->port;
-       struct zfcp_adapter *adapter = port->adapter;
+       struct zfcp_wka_port *wka_port = ct->wka_port;
+       struct zfcp_adapter *adapter = wka_port->adapter;
        struct zfcp_fsf_req *req;
        int ret = -EIO;
 
-       spin_lock_bh(&adapter->req_q.lock);
+       spin_lock_bh(&adapter->req_q_lock);
        if (zfcp_fsf_req_sbal_get(adapter))
                goto out;
 
@@ -1123,7 +1062,7 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool,
                goto failed_send;
 
        req->handler = zfcp_fsf_send_ct_handler;
-       req->qtcb->header.port_handle = port->handle;
+       req->qtcb->header.port_handle = wka_port->handle;
        req->qtcb->bottom.support.service_class = FSF_CLASS_3;
        req->qtcb->bottom.support.timeout = ct->timeout;
        req->data = ct;
@@ -1148,7 +1087,7 @@ failed_send:
        if (erp_action)
                erp_action->fsf_req = NULL;
 out:
-       spin_unlock_bh(&adapter->req_q.lock);
+       spin_unlock_bh(&adapter->req_q_lock);
        return ret;
 }
 
@@ -1218,8 +1157,8 @@ int zfcp_fsf_send_els(struct zfcp_send_els *els)
                       ZFCP_STATUS_COMMON_UNBLOCKED)))
                return -EBUSY;
 
-       spin_lock(&adapter->req_q.lock);
-       if (!atomic_read(&adapter->req_q.count))
+       spin_lock(&adapter->req_q_lock);
+       if (!zfcp_fsf_sbal_available(adapter))
                goto out;
        req = zfcp_fsf_req_create(adapter, FSF_QTCB_SEND_ELS,
                                  ZFCP_REQ_AUTO_CLEANUP, NULL);
@@ -1228,8 +1167,8 @@ int zfcp_fsf_send_els(struct zfcp_send_els *els)
                goto out;
        }
 
-       ret = zfcp_fsf_setup_sbals(req, els->req, els->resp,
-                                  FSF_MAX_SBALS_PER_ELS_REQ);
+       ret = zfcp_fsf_setup_sbals(req, els->req, els->resp, 2);
+
        if (ret)
                goto failed_send;
 
@@ -1252,19 +1191,19 @@ int zfcp_fsf_send_els(struct zfcp_send_els *els)
 failed_send:
        zfcp_fsf_req_free(req);
 out:
-       spin_unlock(&adapter->req_q.lock);
+       spin_unlock(&adapter->req_q_lock);
        return ret;
 }
 
 int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action)
 {
-       volatile struct qdio_buffer_element *sbale;
+       struct qdio_buffer_element *sbale;
        struct zfcp_fsf_req *req;
        struct zfcp_adapter *adapter = erp_action->adapter;
        int retval = -EIO;
 
-       spin_lock_bh(&adapter->req_q.lock);
-       if (!atomic_read(&adapter->req_q.count))
+       spin_lock_bh(&adapter->req_q_lock);
+       if (!zfcp_fsf_sbal_available(adapter))
                goto out;
        req = zfcp_fsf_req_create(adapter,
                                  FSF_QTCB_EXCHANGE_CONFIG_DATA,
@@ -1295,18 +1234,18 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action)
                erp_action->fsf_req = NULL;
        }
 out:
-       spin_unlock_bh(&adapter->req_q.lock);
+       spin_unlock_bh(&adapter->req_q_lock);
        return retval;
 }
 
 int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter,
                                       struct fsf_qtcb_bottom_config *data)
 {
-       volatile struct qdio_buffer_element *sbale;
+       struct qdio_buffer_element *sbale;
        struct zfcp_fsf_req *req = NULL;
        int retval = -EIO;
 
-       spin_lock_bh(&adapter->req_q.lock);
+       spin_lock_bh(&adapter->req_q_lock);
        if (zfcp_fsf_req_sbal_get(adapter))
                goto out;
 
@@ -1334,7 +1273,7 @@ int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter,
        zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
        retval = zfcp_fsf_req_send(req);
 out:
-       spin_unlock_bh(&adapter->req_q.lock);
+       spin_unlock_bh(&adapter->req_q_lock);
        if (!retval)
                wait_event(req->completion_wq,
                           req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
@@ -1351,7 +1290,7 @@ out:
  */
 int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action)
 {
-       volatile struct qdio_buffer_element *sbale;
+       struct qdio_buffer_element *sbale;
        struct zfcp_fsf_req *req;
        struct zfcp_adapter *adapter = erp_action->adapter;
        int retval = -EIO;
@@ -1359,8 +1298,8 @@ int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action)
        if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT))
                return -EOPNOTSUPP;
 
-       spin_lock_bh(&adapter->req_q.lock);
-       if (!atomic_read(&adapter->req_q.count))
+       spin_lock_bh(&adapter->req_q_lock);
+       if (!zfcp_fsf_sbal_available(adapter))
                goto out;
        req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA,
                                  ZFCP_REQ_AUTO_CLEANUP,
@@ -1385,7 +1324,7 @@ int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action)
                erp_action->fsf_req = NULL;
        }
 out:
-       spin_unlock_bh(&adapter->req_q.lock);
+       spin_unlock_bh(&adapter->req_q_lock);
        return retval;
 }
 
@@ -1398,15 +1337,15 @@ out:
 int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter,
                                     struct fsf_qtcb_bottom_port *data)
 {
-       volatile struct qdio_buffer_element *sbale;
+       struct qdio_buffer_element *sbale;
        struct zfcp_fsf_req *req = NULL;
        int retval = -EIO;
 
        if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT))
                return -EOPNOTSUPP;
 
-       spin_lock_bh(&adapter->req_q.lock);
-       if (!atomic_read(&adapter->req_q.count))
+       spin_lock_bh(&adapter->req_q_lock);
+       if (!zfcp_fsf_sbal_available(adapter))
                goto out;
 
        req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, 0,
@@ -1427,7 +1366,7 @@ int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter,
        zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
        retval = zfcp_fsf_req_send(req);
 out:
-       spin_unlock_bh(&adapter->req_q.lock);
+       spin_unlock_bh(&adapter->req_q_lock);
        if (!retval)
                wait_event(req->completion_wq,
                           req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
@@ -1443,7 +1382,7 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req)
        struct fsf_plogi *plogi;
 
        if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
-               goto skip_fsfstatus;
+               return;
 
        switch (header->fsf_status) {
        case FSF_PORT_ALREADY_OPEN:
@@ -1453,9 +1392,9 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req)
                break;
        case FSF_MAXIMUM_NUMBER_OF_PORTS_EXCEEDED:
                dev_warn(&req->adapter->ccw_device->dev,
-                        "The adapter is out of resources. The remote port "
-                        "0x%016Lx could not be opened, disabling it.\n",
-                        port->wwpn);
+                        "Not enough FCP adapter resources to open "
+                        "remote port 0x%016Lx\n",
+                        (unsigned long long)port->wwpn);
                zfcp_erp_port_failed(port, 31, req);
                req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                break;
@@ -1467,8 +1406,8 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req)
                        break;
                case FSF_SQ_NO_RETRY_POSSIBLE:
                        dev_warn(&req->adapter->ccw_device->dev,
-                                "The remote port 0x%016Lx could not be "
-                                "opened. Disabling it.\n", port->wwpn);
+                                "Remote port 0x%016Lx could not be opened\n",
+                                (unsigned long long)port->wwpn);
                        zfcp_erp_port_failed(port, 32, req);
                        req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                        break;
@@ -1496,9 +1435,6 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req)
                 * another GID_PN straight after a port has been opened.
                 * Alternately, an ADISC/PDISC ELS should suffice, as well.
                 */
-               if (atomic_read(&port->status) & ZFCP_STATUS_PORT_NO_WWPN)
-                       break;
-
                plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els;
                if (req->qtcb->bottom.support.els1_length >= sizeof(*plogi)) {
                        if (plogi->serv_param.wwpn != port->wwpn)
@@ -1514,9 +1450,6 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req)
                req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                break;
        }
-
-skip_fsfstatus:
-       atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING, &port->status);
 }
 
 /**
@@ -1526,12 +1459,12 @@ skip_fsfstatus:
  */
 int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action)
 {
-       volatile struct qdio_buffer_element *sbale;
+       struct qdio_buffer_element *sbale;
        struct zfcp_adapter *adapter = erp_action->adapter;
        struct zfcp_fsf_req *req;
        int retval = -EIO;
 
-       spin_lock_bh(&adapter->req_q.lock);
+       spin_lock_bh(&adapter->req_q_lock);
        if (zfcp_fsf_req_sbal_get(adapter))
                goto out;
 
@@ -1553,7 +1486,6 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action)
        req->data = erp_action->port;
        req->erp_action = erp_action;
        erp_action->fsf_req = req;
-       atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &erp_action->port->status);
 
        zfcp_fsf_start_erp_timer(req);
        retval = zfcp_fsf_req_send(req);
@@ -1562,7 +1494,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action)
                erp_action->fsf_req = NULL;
        }
 out:
-       spin_unlock_bh(&adapter->req_q.lock);
+       spin_unlock_bh(&adapter->req_q_lock);
        return retval;
 }
 
@@ -1571,7 +1503,7 @@ static void zfcp_fsf_close_port_handler(struct zfcp_fsf_req *req)
        struct zfcp_port *port = req->data;
 
        if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
-               goto skip_fsfstatus;
+               return;
 
        switch (req->qtcb->header.fsf_status) {
        case FSF_PORT_HANDLE_NOT_VALID:
@@ -1586,9 +1518,6 @@ static void zfcp_fsf_close_port_handler(struct zfcp_fsf_req *req)
                                            ZFCP_CLEAR);
                break;
        }
-
-skip_fsfstatus:
-       atomic_clear_mask(ZFCP_STATUS_COMMON_CLOSING, &port->status);
 }
 
 /**
@@ -1598,12 +1527,12 @@ skip_fsfstatus:
  */
 int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action)
 {
-       volatile struct qdio_buffer_element *sbale;
+       struct qdio_buffer_element *sbale;
        struct zfcp_adapter *adapter = erp_action->adapter;
        struct zfcp_fsf_req *req;
        int retval = -EIO;
 
-       spin_lock_bh(&adapter->req_q.lock);
+       spin_lock_bh(&adapter->req_q_lock);
        if (zfcp_fsf_req_sbal_get(adapter))
                goto out;
 
@@ -1624,7 +1553,6 @@ int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action)
        req->erp_action = erp_action;
        req->qtcb->header.port_handle = erp_action->port->handle;
        erp_action->fsf_req = req;
-       atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING, &erp_action->port->status);
 
        zfcp_fsf_start_erp_timer(req);
        retval = zfcp_fsf_req_send(req);
@@ -1633,7 +1561,131 @@ int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action)
                erp_action->fsf_req = NULL;
        }
 out:
-       spin_unlock_bh(&adapter->req_q.lock);
+       spin_unlock_bh(&adapter->req_q_lock);
+       return retval;
+}
+
+static void zfcp_fsf_open_wka_port_handler(struct zfcp_fsf_req *req)
+{
+       struct zfcp_wka_port *wka_port = req->data;
+       struct fsf_qtcb_header *header = &req->qtcb->header;
+
+       if (req->status & ZFCP_STATUS_FSFREQ_ERROR) {
+               wka_port->status = ZFCP_WKA_PORT_OFFLINE;
+               goto out;
+       }
+
+       switch (header->fsf_status) {
+       case FSF_MAXIMUM_NUMBER_OF_PORTS_EXCEEDED:
+               dev_warn(&req->adapter->ccw_device->dev,
+                        "Opening WKA port 0x%x failed\n", wka_port->d_id);
+       case FSF_ADAPTER_STATUS_AVAILABLE:
+               req->status |= ZFCP_STATUS_FSFREQ_ERROR;
+       case FSF_ACCESS_DENIED:
+               wka_port->status = ZFCP_WKA_PORT_OFFLINE;
+               break;
+       case FSF_PORT_ALREADY_OPEN:
+       case FSF_GOOD:
+               wka_port->handle = header->port_handle;
+               wka_port->status = ZFCP_WKA_PORT_ONLINE;
+       }
+out:
+       wake_up(&wka_port->completion_wq);
+}
+
+/**
+ * zfcp_fsf_open_wka_port - create and send open wka-port request
+ * @wka_port: pointer to struct zfcp_wka_port
+ * Returns: 0 on success, error otherwise
+ */
+int zfcp_fsf_open_wka_port(struct zfcp_wka_port *wka_port)
+{
+       struct qdio_buffer_element *sbale;
+       struct zfcp_adapter *adapter = wka_port->adapter;
+       struct zfcp_fsf_req *req;
+       int retval = -EIO;
+
+       spin_lock_bh(&adapter->req_q_lock);
+       if (zfcp_fsf_req_sbal_get(adapter))
+               goto out;
+
+       req = zfcp_fsf_req_create(adapter,
+                                 FSF_QTCB_OPEN_PORT_WITH_DID,
+                                 ZFCP_REQ_AUTO_CLEANUP,
+                                 adapter->pool.fsf_req_erp);
+       if (unlikely(IS_ERR(req))) {
+               retval = PTR_ERR(req);
+               goto out;
+       }
+
+       sbale = zfcp_qdio_sbale_req(req);
+       sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
+       sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
+
+       req->handler = zfcp_fsf_open_wka_port_handler;
+       req->qtcb->bottom.support.d_id = wka_port->d_id;
+       req->data = wka_port;
+
+       zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
+       retval = zfcp_fsf_req_send(req);
+       if (retval)
+               zfcp_fsf_req_free(req);
+out:
+       spin_unlock_bh(&adapter->req_q_lock);
+       return retval;
+}
+
+static void zfcp_fsf_close_wka_port_handler(struct zfcp_fsf_req *req)
+{
+       struct zfcp_wka_port *wka_port = req->data;
+
+       if (req->qtcb->header.fsf_status == FSF_PORT_HANDLE_NOT_VALID) {
+               req->status |= ZFCP_STATUS_FSFREQ_ERROR;
+               zfcp_erp_adapter_reopen(wka_port->adapter, 0, 84, req);
+       }
+
+       wka_port->status = ZFCP_WKA_PORT_OFFLINE;
+       wake_up(&wka_port->completion_wq);
+}
+
+/**
+ * zfcp_fsf_close_wka_port - create and send close wka port request
+ * @erp_action: pointer to struct zfcp_erp_action
+ * Returns: 0 on success, error otherwise
+ */
+int zfcp_fsf_close_wka_port(struct zfcp_wka_port *wka_port)
+{
+       struct qdio_buffer_element *sbale;
+       struct zfcp_adapter *adapter = wka_port->adapter;
+       struct zfcp_fsf_req *req;
+       int retval = -EIO;
+
+       spin_lock_bh(&adapter->req_q_lock);
+       if (zfcp_fsf_req_sbal_get(adapter))
+               goto out;
+
+       req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_PORT,
+                                 ZFCP_REQ_AUTO_CLEANUP,
+                                 adapter->pool.fsf_req_erp);
+       if (unlikely(IS_ERR(req))) {
+               retval = PTR_ERR(req);
+               goto out;
+       }
+
+       sbale = zfcp_qdio_sbale_req(req);
+       sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
+       sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
+
+       req->handler = zfcp_fsf_close_wka_port_handler;
+       req->data = wka_port;
+       req->qtcb->header.port_handle = wka_port->handle;
+
+       zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
+       retval = zfcp_fsf_req_send(req);
+       if (retval)
+               zfcp_fsf_req_free(req);
+out:
+       spin_unlock_bh(&adapter->req_q_lock);
        return retval;
 }
 
@@ -1695,12 +1747,12 @@ skip_fsfstatus:
  */
 int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action)
 {
-       volatile struct qdio_buffer_element *sbale;
+       struct qdio_buffer_element *sbale;
        struct zfcp_adapter *adapter = erp_action->adapter;
        struct zfcp_fsf_req *req;
        int retval = -EIO;
 
-       spin_lock_bh(&adapter->req_q.lock);
+       spin_lock_bh(&adapter->req_q_lock);
        if (zfcp_fsf_req_sbal_get(adapter))
                goto out;
 
@@ -1731,7 +1783,7 @@ int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action)
                erp_action->fsf_req = NULL;
        }
 out:
-       spin_unlock_bh(&adapter->req_q.lock);
+       spin_unlock_bh(&adapter->req_q_lock);
        return retval;
 }
 
@@ -1746,7 +1798,7 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req)
        int exclusive, readwrite;
 
        if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
-               goto skip_fsfstatus;
+               return;
 
        atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED |
                          ZFCP_STATUS_COMMON_ACCESS_BOXED |
@@ -1774,14 +1826,12 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req)
        case FSF_LUN_SHARING_VIOLATION:
                if (header->fsf_status_qual.word[0])
                        dev_warn(&adapter->ccw_device->dev,
-                                "FCP-LUN 0x%Lx at the remote port "
-                                "with WWPN 0x%Lx "
-                                "connected to the adapter "
-                                "is already in use in LPAR%d, CSS%d.\n",
-                                unit->fcp_lun,
-                                unit->port->wwpn,
-                                queue_designator->hla,
-                                queue_designator->cssid);
+                                "LUN 0x%Lx on port 0x%Lx is already in "
+                                "use by CSS%d, MIF Image ID %x\n",
+                                (unsigned long long)unit->fcp_lun,
+                                (unsigned long long)unit->port->wwpn,
+                                queue_designator->cssid,
+                                queue_designator->hla);
                else
                        zfcp_act_eval_err(adapter,
                                          header->fsf_status_qual.word[2]);
@@ -1792,9 +1842,10 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req)
                break;
        case FSF_MAXIMUM_NUMBER_OF_LUNS_EXCEEDED:
                dev_warn(&adapter->ccw_device->dev,
-                        "The adapter ran out of resources. There is no "
-                        "handle available for unit 0x%016Lx on port 0x%016Lx.",
-                        unit->fcp_lun, unit->port->wwpn);
+                        "No handle is available for LUN "
+                        "0x%016Lx on port 0x%016Lx\n",
+                        (unsigned long long)unit->fcp_lun,
+                        (unsigned long long)unit->port->wwpn);
                zfcp_erp_unit_failed(unit, 34, req);
                /* fall through */
        case FSF_INVALID_COMMAND_OPTION:
@@ -1831,26 +1882,29 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req)
                                atomic_set_mask(ZFCP_STATUS_UNIT_READONLY,
                                                &unit->status);
                                dev_info(&adapter->ccw_device->dev,
-                                        "Read-only access for unit 0x%016Lx "
-                                        "on port 0x%016Lx.\n",
-                                        unit->fcp_lun, unit->port->wwpn);
+                                        "SCSI device at LUN 0x%016Lx on port "
+                                        "0x%016Lx opened read-only\n",
+                                        (unsigned long long)unit->fcp_lun,
+                                        (unsigned long long)unit->port->wwpn);
                        }
 
                        if (exclusive && !readwrite) {
                                dev_err(&adapter->ccw_device->dev,
-                                       "Exclusive access of read-only unit "
-                                       "0x%016Lx on port 0x%016Lx not "
-                                       "supported, disabling unit.\n",
-                                       unit->fcp_lun, unit->port->wwpn);
+                                       "Exclusive read-only access not "
+                                       "supported (unit 0x%016Lx, "
+                                       "port 0x%016Lx)\n",
+                                       (unsigned long long)unit->fcp_lun,
+                                       (unsigned long long)unit->port->wwpn);
                                zfcp_erp_unit_failed(unit, 35, req);
                                req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                                zfcp_erp_unit_shutdown(unit, 0, 80, req);
                        } else if (!exclusive && readwrite) {
                                dev_err(&adapter->ccw_device->dev,
-                                       "Shared access of read-write unit "
-                                       "0x%016Lx on port 0x%016Lx not "
-                                       "supported, disabling unit.\n",
-                                       unit->fcp_lun, unit->port->wwpn);
+                                       "Shared read-write access not "
+                                       "supported (unit 0x%016Lx, port "
+                                       "0x%016Lx\n)",
+                                       (unsigned long long)unit->fcp_lun,
+                                       (unsigned long long)unit->port->wwpn);
                                zfcp_erp_unit_failed(unit, 36, req);
                                req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                                zfcp_erp_unit_shutdown(unit, 0, 81, req);
@@ -1858,9 +1912,6 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req)
                }
                break;
        }
-
-skip_fsfstatus:
-       atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING, &unit->status);
 }
 
 /**
@@ -1870,12 +1921,12 @@ skip_fsfstatus:
  */
 int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action)
 {
-       volatile struct qdio_buffer_element *sbale;
+       struct qdio_buffer_element *sbale;
        struct zfcp_adapter *adapter = erp_action->adapter;
        struct zfcp_fsf_req *req;
        int retval = -EIO;
 
-       spin_lock_bh(&adapter->req_q.lock);
+       spin_lock_bh(&adapter->req_q_lock);
        if (zfcp_fsf_req_sbal_get(adapter))
                goto out;
 
@@ -1901,8 +1952,6 @@ int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action)
        if (!(adapter->connection_features & FSF_FEATURE_NPIV_MODE))
                req->qtcb->bottom.support.option = FSF_OPEN_LUN_SUPPRESS_BOXING;
 
-       atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &erp_action->unit->status);
-
        zfcp_fsf_start_erp_timer(req);
        retval = zfcp_fsf_req_send(req);
        if (retval) {
@@ -1910,7 +1959,7 @@ int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action)
                erp_action->fsf_req = NULL;
        }
 out:
-       spin_unlock_bh(&adapter->req_q.lock);
+       spin_unlock_bh(&adapter->req_q_lock);
        return retval;
 }
 
@@ -1919,7 +1968,7 @@ static void zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *req)
        struct zfcp_unit *unit = req->data;
 
        if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
-               goto skip_fsfstatus;
+               return;
 
        switch (req->qtcb->header.fsf_status) {
        case FSF_PORT_HANDLE_NOT_VALID:
@@ -1949,8 +1998,6 @@ static void zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *req)
                atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status);
                break;
        }
-skip_fsfstatus:
-       atomic_clear_mask(ZFCP_STATUS_COMMON_CLOSING, &unit->status);
 }
 
 /**
@@ -1960,12 +2007,12 @@ skip_fsfstatus:
  */
 int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action)
 {
-       volatile struct qdio_buffer_element *sbale;
+       struct qdio_buffer_element *sbale;
        struct zfcp_adapter *adapter = erp_action->adapter;
        struct zfcp_fsf_req *req;
        int retval = -EIO;
 
-       spin_lock_bh(&adapter->req_q.lock);
+       spin_lock_bh(&adapter->req_q_lock);
        if (zfcp_fsf_req_sbal_get(adapter))
                goto out;
        req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_LUN,
@@ -1986,7 +2033,6 @@ int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action)
        req->data = erp_action->unit;
        req->erp_action = erp_action;
        erp_action->fsf_req = req;
-       atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING, &erp_action->unit->status);
 
        zfcp_fsf_start_erp_timer(req);
        retval = zfcp_fsf_req_send(req);
@@ -1995,7 +2041,7 @@ int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action)
                erp_action->fsf_req = NULL;
        }
 out:
-       spin_unlock_bh(&adapter->req_q.lock);
+       spin_unlock_bh(&adapter->req_q_lock);
        return retval;
 }
 
@@ -2156,21 +2202,21 @@ static void zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *req)
                break;
        case FSF_DIRECTION_INDICATOR_NOT_VALID:
                dev_err(&req->adapter->ccw_device->dev,
-                       "Invalid data direction (%d) given for unit "
-                       "0x%016Lx on port 0x%016Lx, shutting down "
-                       "adapter.\n",
+                       "Incorrect direction %d, unit 0x%016Lx on port "
+                       "0x%016Lx closed\n",
                        req->qtcb->bottom.io.data_direction,
-                       unit->fcp_lun, unit->port->wwpn);
+                       (unsigned long long)unit->fcp_lun,
+                       (unsigned long long)unit->port->wwpn);
                zfcp_erp_adapter_shutdown(unit->port->adapter, 0, 133, req);
                req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                break;
        case FSF_CMND_LENGTH_NOT_VALID:
                dev_err(&req->adapter->ccw_device->dev,
-                       "An invalid control-data-block length field (%d) "
-                       "was found in a command for unit 0x%016Lx on port "
-                       "0x%016Lx. Shutting down adapter.\n",
+                       "Incorrect CDB length %d, unit 0x%016Lx on "
+                       "port 0x%016Lx closed\n",
                        req->qtcb->bottom.io.fcp_cmnd_length,
-                       unit->fcp_lun, unit->port->wwpn);
+                       (unsigned long long)unit->fcp_lun,
+                       (unsigned long long)unit->port->wwpn);
                zfcp_erp_adapter_shutdown(unit->port->adapter, 0, 134, req);
                req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                break;
@@ -2201,6 +2247,20 @@ skip_fsfstatus:
        }
 }
 
+static void zfcp_set_fcp_dl(struct fcp_cmnd_iu *fcp_cmd, u32 fcp_dl)
+{
+       u32 *fcp_dl_ptr;
+
+       /*
+        * fcp_dl_addr = start address of fcp_cmnd structure +
+        * size of fixed part + size of dynamically sized add_dcp_cdb field
+        * SEE FCP-2 documentation
+        */
+       fcp_dl_ptr = (u32 *) ((unsigned char *) &fcp_cmd[1] +
+                       (fcp_cmd->add_fcp_cdb_length << 2));
+       *fcp_dl_ptr = fcp_dl;
+}
+
 /**
  * zfcp_fsf_send_fcp_command_task - initiate an FCP command (for a SCSI command)
  * @adapter: adapter where scsi command is issued
@@ -2223,8 +2283,8 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
                       ZFCP_STATUS_COMMON_UNBLOCKED)))
                return -EBUSY;
 
-       spin_lock(&adapter->req_q.lock);
-       if (!atomic_read(&adapter->req_q.count))
+       spin_lock(&adapter->req_q_lock);
+       if (!zfcp_fsf_sbal_available(adapter))
                goto out;
        req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags,
                                  adapter->pool.fsf_req_scsi);
@@ -2286,7 +2346,7 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
        memcpy(fcp_cmnd_iu->fcp_cdb, scsi_cmnd->cmnd, scsi_cmnd->cmd_len);
 
        req->qtcb->bottom.io.fcp_cmnd_length = sizeof(struct fcp_cmnd_iu) +
-               fcp_cmnd_iu->add_fcp_cdb_length + sizeof(fcp_dl_t);
+               fcp_cmnd_iu->add_fcp_cdb_length + sizeof(u32);
 
        real_bytes = zfcp_qdio_sbals_from_sg(req, sbtype,
                                             scsi_sglist(scsi_cmnd),
@@ -2296,10 +2356,10 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
                        retval = -EIO;
                else {
                        dev_err(&adapter->ccw_device->dev,
-                               "SCSI request too large. "
-                               "Shutting down unit 0x%016Lx on port "
-                               "0x%016Lx.\n", unit->fcp_lun,
-                               unit->port->wwpn);
+                               "Oversize data package, unit 0x%016Lx "
+                               "on port 0x%016Lx closed\n",
+                               (unsigned long long)unit->fcp_lun,
+                               (unsigned long long)unit->port->wwpn);
                        zfcp_erp_unit_shutdown(unit, 0, 131, req);
                        retval = -EINVAL;
                }
@@ -2322,7 +2382,7 @@ failed_scsi_cmnd:
        zfcp_fsf_req_free(req);
        scsi_cmnd->host_scribble = NULL;
 out:
-       spin_unlock(&adapter->req_q.lock);
+       spin_unlock(&adapter->req_q_lock);
        return retval;
 }
 
@@ -2338,7 +2398,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_adapter *adapter,
                                           struct zfcp_unit *unit,
                                           u8 tm_flags, int req_flags)
 {
-       volatile struct qdio_buffer_element *sbale;
+       struct qdio_buffer_element *sbale;
        struct zfcp_fsf_req *req = NULL;
        struct fcp_cmnd_iu *fcp_cmnd_iu;
 
@@ -2346,8 +2406,8 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_adapter *adapter,
                       ZFCP_STATUS_COMMON_UNBLOCKED)))
                return NULL;
 
-       spin_lock(&adapter->req_q.lock);
-       if (!atomic_read(&adapter->req_q.count))
+       spin_lock(&adapter->req_q_lock);
+       if (!zfcp_fsf_sbal_available(adapter))
                goto out;
        req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags,
                                  adapter->pool.fsf_req_scsi);
@@ -2362,7 +2422,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_adapter *adapter,
        req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND;
        req->qtcb->bottom.io.service_class = FSF_CLASS_3;
        req->qtcb->bottom.io.fcp_cmnd_length =  sizeof(struct fcp_cmnd_iu) +
-                                               sizeof(fcp_dl_t);
+                                               sizeof(u32);
 
        sbale = zfcp_qdio_sbale_req(req);
        sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE;
@@ -2379,7 +2439,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_adapter *adapter,
        zfcp_fsf_req_free(req);
        req = NULL;
 out:
-       spin_unlock(&adapter->req_q.lock);
+       spin_unlock(&adapter->req_q_lock);
        return req;
 }
 
@@ -2398,7 +2458,7 @@ static void zfcp_fsf_control_file_handler(struct zfcp_fsf_req *req)
 struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter,
                                           struct zfcp_fsf_cfdc *fsf_cfdc)
 {
-       volatile struct qdio_buffer_element *sbale;
+       struct qdio_buffer_element *sbale;
        struct zfcp_fsf_req *req = NULL;
        struct fsf_qtcb_bottom_support *bottom;
        int direction, retval = -EIO, bytes;
@@ -2417,7 +2477,7 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter,
                return ERR_PTR(-EINVAL);
        }
 
-       spin_lock_bh(&adapter->req_q.lock);
+       spin_lock_bh(&adapter->req_q_lock);
        if (zfcp_fsf_req_sbal_get(adapter))
                goto out;
 
@@ -2447,7 +2507,7 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter,
        zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
        retval = zfcp_fsf_req_send(req);
 out:
-       spin_unlock_bh(&adapter->req_q.lock);
+       spin_unlock_bh(&adapter->req_q_lock);
 
        if (!retval) {
                wait_event(req->completion_wq,
index bf94b4da0763c09e642a150cda24c725df963e89..fd3a88777ac8ea200aacb81bbfe72fb9792d86df 100644 (file)
 #define FSF_MAXIMUM_NUMBER_OF_LUNS_EXCEEDED    0x00000041
 #define FSF_ELS_COMMAND_REJECTED               0x00000050
 #define FSF_GENERIC_COMMAND_REJECTED           0x00000051
-#define FSF_OPERATION_PARTIALLY_SUCCESSFUL     0x00000052
-#define FSF_AUTHORIZATION_FAILURE              0x00000053
-#define FSF_CFDC_ERROR_DETECTED                        0x00000054
-#define FSF_CONTROL_FILE_UPDATE_ERROR          0x00000055
-#define FSF_CONTROL_FILE_TOO_LARGE             0x00000056
-#define FSF_ACCESS_CONFLICT_DETECTED           0x00000057
-#define FSF_CONFLICTS_OVERRULED                        0x00000058
 #define FSF_PORT_BOXED                         0x00000059
 #define FSF_LUN_BOXED                          0x0000005A
 #define FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE    0x0000005B
@@ -85,9 +78,7 @@
 #define FSF_REQUEST_SIZE_TOO_LARGE             0x00000061
 #define FSF_RESPONSE_SIZE_TOO_LARGE            0x00000062
 #define FSF_SBAL_MISMATCH                      0x00000063
-#define FSF_OPEN_PORT_WITHOUT_PRLI             0x00000064
 #define FSF_ADAPTER_STATUS_AVAILABLE           0x000000AD
-#define FSF_FCP_RSP_AVAILABLE                  0x000000AF
 #define FSF_UNKNOWN_COMMAND                    0x000000E2
 #define FSF_UNKNOWN_OP_SUBTYPE                  0x000000E3
 #define FSF_INVALID_COMMAND_OPTION              0x000000E5
 #define FSF_SQ_RETRY_IF_POSSIBLE               0x02
 #define FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED      0x03
 #define FSF_SQ_INVOKE_LINK_TEST_PROCEDURE      0x04
-#define FSF_SQ_ULP_PROGRAMMING_ERROR           0x05
 #define FSF_SQ_COMMAND_ABORTED                 0x06
 #define FSF_SQ_NO_RETRY_POSSIBLE               0x07
 
-/* FSF status qualifier for CFDC commands */
-#define FSF_SQ_CFDC_HARDENED_ON_SE             0x00000000
-#define FSF_SQ_CFDC_COULD_NOT_HARDEN_ON_SE     0x00000001
-#define FSF_SQ_CFDC_COULD_NOT_HARDEN_ON_SE2    0x00000002
-/* CFDC subtable codes */
-#define FSF_SQ_CFDC_SUBTABLE_OS                        0x0001
-#define FSF_SQ_CFDC_SUBTABLE_PORT_WWPN         0x0002
-#define FSF_SQ_CFDC_SUBTABLE_PORT_DID          0x0003
-#define FSF_SQ_CFDC_SUBTABLE_LUN               0x0004
-
 /* FSF status qualifier (most significant 4 bytes), local link down */
 #define FSF_PSQ_LINK_NO_LIGHT                  0x00000004
 #define FSF_PSQ_LINK_WRAP_PLUG                 0x00000008
 #define FSF_STATUS_READ_LINK_UP                0x00000006
 #define FSF_STATUS_READ_NOTIFICATION_LOST      0x00000009
 #define FSF_STATUS_READ_CFDC_UPDATED           0x0000000A
-#define FSF_STATUS_READ_CFDC_HARDENED          0x0000000B
 #define FSF_STATUS_READ_FEATURE_UPDATE_ALERT   0x0000000C
 
 /* status subtypes in status read buffer */
 
 /* status subtypes for unsolicited status notification lost */
 #define FSF_STATUS_READ_SUB_INCOMING_ELS       0x00000001
-#define FSF_STATUS_READ_SUB_SENSE_DATA         0x00000002
-#define FSF_STATUS_READ_SUB_LINK_STATUS                0x00000004
-#define FSF_STATUS_READ_SUB_PORT_CLOSED                0x00000008
-#define FSF_STATUS_READ_SUB_BIT_ERROR_THRESHOLD        0x00000010
 #define FSF_STATUS_READ_SUB_ACT_UPDATED                0x00000020
-#define FSF_STATUS_READ_SUB_ACT_HARDENED       0x00000040
-#define FSF_STATUS_READ_SUB_FEATURE_UPDATE_ALERT 0x00000080
-
-/* status subtypes for CFDC */
-#define FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE        0x00000002
-#define FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE2 0x0000000F
 
 /* topologie that is detected by the adapter */
-#define FSF_TOPO_ERROR                         0x00000000
 #define FSF_TOPO_P2P                           0x00000001
 #define FSF_TOPO_FABRIC                                0x00000002
 #define FSF_TOPO_AL                            0x00000003
 /* data direction for FCP commands */
 #define FSF_DATADIR_WRITE                      0x00000001
 #define FSF_DATADIR_READ                       0x00000002
-#define FSF_DATADIR_READ_WRITE                 0x00000003
 #define FSF_DATADIR_CMND                       0x00000004
 
 /* fc service class */
-#define FSF_CLASS_1                            0x00000001
-#define FSF_CLASS_2                            0x00000002
 #define FSF_CLASS_3                            0x00000003
 
 /* SBAL chaining */
 #define FSF_MAX_SBALS_PER_REQ                  36
-#define FSF_MAX_SBALS_PER_ELS_REQ              2
 
 /* logging space behind QTCB */
 #define FSF_QTCB_LOG_SIZE                      1024
 #define FSF_FEATURE_LUN_SHARING                        0x00000004
 #define FSF_FEATURE_NOTIFICATION_LOST          0x00000008
 #define FSF_FEATURE_HBAAPI_MANAGEMENT           0x00000010
-#define FSF_FEATURE_ELS_CT_CHAINED_SBALS        0x00000020
 #define FSF_FEATURE_UPDATE_ALERT               0x00000100
 #define FSF_FEATURE_MEASUREMENT_DATA           0x00000200
 
 /* host connection features */
 #define FSF_FEATURE_NPIV_MODE                  0x00000001
-#define FSF_FEATURE_VM_ASSIGNED_WWPN           0x00000002
 
 /* option */
 #define FSF_OPEN_LUN_SUPPRESS_BOXING           0x00000001
-#define FSF_OPEN_LUN_REPLICATE_SENSE           0x00000002
-
-/* adapter types */
-#define FSF_ADAPTER_TYPE_FICON                  0x00000001
-#define FSF_ADAPTER_TYPE_FICON_EXPRESS          0x00000002
-
-/* port types */
-#define FSF_HBA_PORTTYPE_UNKNOWN               0x00000001
-#define FSF_HBA_PORTTYPE_NOTPRESENT            0x00000003
-#define FSF_HBA_PORTTYPE_NPORT                 0x00000005
-#define FSF_HBA_PORTTYPE_PTP                   0x00000021
-/* following are not defined and used by FSF Spec
-   but are additionally defined by FC-HBA */
-#define FSF_HBA_PORTTYPE_OTHER                 0x00000002
-#define FSF_HBA_PORTTYPE_NOTPRESENT            0x00000003
-#define FSF_HBA_PORTTYPE_NLPORT                        0x00000006
-#define FSF_HBA_PORTTYPE_FLPORT                        0x00000007
-#define FSF_HBA_PORTTYPE_FPORT                 0x00000008
-#define FSF_HBA_PORTTYPE_LPORT                 0x00000020
-
-/* port states */
-#define FSF_HBA_PORTSTATE_UNKNOWN              0x00000001
-#define FSF_HBA_PORTSTATE_ONLINE               0x00000002
-#define FSF_HBA_PORTSTATE_OFFLINE              0x00000003
-#define FSF_HBA_PORTSTATE_LINKDOWN             0x00000006
-#define FSF_HBA_PORTSTATE_ERROR                        0x00000007
-
-/* IO states of adapter */
-#define FSF_IOSTAT_NPORT_RJT                   0x00000004
-#define FSF_IOSTAT_FABRIC_RJT                  0x00000005
-#define FSF_IOSTAT_LS_RJT                      0x00000009
 
 /* open LUN access flags*/
-#define FSF_UNIT_ACCESS_OPEN_LUN_ALLOWED       0x01000000
 #define FSF_UNIT_ACCESS_EXCLUSIVE              0x02000000
 #define FSF_UNIT_ACCESS_OUTBOUND_TRANSFER      0x10000000
 
@@ -265,11 +195,6 @@ struct fsf_queue_designator {
        u32 res1;
 } __attribute__ ((packed));
 
-struct fsf_port_closed_payload {
-       struct fsf_queue_designator queue_designator;
-       u32                         port_handle;
-} __attribute__ ((packed));
-
 struct fsf_bit_error_payload {
        u32 res1;
        u32 link_failure_error_count;
index 69d632d851d9205e790c151dc6df5b352d62cd50..3e05080e62d410c05afc802f3deb67ba215e40c4 100644 (file)
@@ -28,7 +28,7 @@ static int zfcp_qdio_buffers_enqueue(struct qdio_buffer **sbal)
        return 0;
 }
 
-static volatile struct qdio_buffer_element *
+static struct qdio_buffer_element *
 zfcp_qdio_sbale(struct zfcp_qdio_queue *q, int sbal_idx, int sbale_idx)
 {
        return &q->sbal[sbal_idx]->element[sbale_idx];
@@ -57,7 +57,7 @@ void zfcp_qdio_free(struct zfcp_adapter *adapter)
 
 static void zfcp_qdio_handler_error(struct zfcp_adapter *adapter, u8 id)
 {
-       dev_warn(&adapter->ccw_device->dev, "QDIO problem occurred.\n");
+       dev_warn(&adapter->ccw_device->dev, "A QDIO problem occurred\n");
 
        zfcp_erp_adapter_reopen(adapter,
                                ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
@@ -145,7 +145,7 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
 {
        struct zfcp_adapter *adapter = (struct zfcp_adapter *) parm;
        struct zfcp_qdio_queue *queue = &adapter->resp_q;
-       volatile struct qdio_buffer_element *sbale;
+       struct qdio_buffer_element *sbale;
        int sbal_idx, sbale_idx, sbal_no;
 
        if (unlikely(qdio_err)) {
@@ -174,8 +174,8 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
 
                if (unlikely(!(sbale->flags & SBAL_FLAGS_LAST_ENTRY)))
                        dev_warn(&adapter->ccw_device->dev,
-                                "Protocol violation by adapter. "
-                                "Continuing operations.\n");
+                                "A QDIO protocol error occurred, "
+                                "operations continue\n");
        }
 
        /*
@@ -190,8 +190,7 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
  * @fsf_req: pointer to struct fsf_req
  * Returns: pointer to qdio_buffer_element (SBALE) structure
  */
-volatile struct qdio_buffer_element *
-zfcp_qdio_sbale_req(struct zfcp_fsf_req *req)
+struct qdio_buffer_element *zfcp_qdio_sbale_req(struct zfcp_fsf_req *req)
 {
        return zfcp_qdio_sbale(&req->adapter->req_q, req->sbal_last, 0);
 }
@@ -201,8 +200,7 @@ zfcp_qdio_sbale_req(struct zfcp_fsf_req *req)
  * @fsf_req: pointer to struct fsf_req
  * Returns: pointer to qdio_buffer_element (SBALE) structure
  */
-volatile struct qdio_buffer_element *
-zfcp_qdio_sbale_curr(struct zfcp_fsf_req *req)
+struct qdio_buffer_element *zfcp_qdio_sbale_curr(struct zfcp_fsf_req *req)
 {
        return zfcp_qdio_sbale(&req->adapter->req_q, req->sbal_last,
                               req->sbale_curr);
@@ -216,10 +214,10 @@ static void zfcp_qdio_sbal_limit(struct zfcp_fsf_req *fsf_req, int max_sbals)
                                        % QDIO_MAX_BUFFERS_PER_Q;
 }
 
-static volatile struct qdio_buffer_element *
+static struct qdio_buffer_element *
 zfcp_qdio_sbal_chain(struct zfcp_fsf_req *fsf_req, unsigned long sbtype)
 {
-       volatile struct qdio_buffer_element *sbale;
+       struct qdio_buffer_element *sbale;
 
        /* set last entry flag in current SBALE of current SBAL */
        sbale = zfcp_qdio_sbale_curr(fsf_req);
@@ -250,7 +248,7 @@ zfcp_qdio_sbal_chain(struct zfcp_fsf_req *fsf_req, unsigned long sbtype)
        return sbale;
 }
 
-static volatile struct qdio_buffer_element *
+static struct qdio_buffer_element *
 zfcp_qdio_sbale_next(struct zfcp_fsf_req *fsf_req, unsigned long sbtype)
 {
        if (fsf_req->sbale_curr == ZFCP_LAST_SBALE_PER_SBAL)
@@ -273,7 +271,7 @@ static int zfcp_qdio_fill_sbals(struct zfcp_fsf_req *fsf_req,
                                unsigned int sbtype, void *start_addr,
                                unsigned int total_length)
 {
-       volatile struct qdio_buffer_element *sbale;
+       struct qdio_buffer_element *sbale;
        unsigned long remaining, length;
        void *addr;
 
@@ -282,6 +280,7 @@ static int zfcp_qdio_fill_sbals(struct zfcp_fsf_req *fsf_req,
             addr += length, remaining -= length) {
                sbale = zfcp_qdio_sbale_next(fsf_req, sbtype);
                if (!sbale) {
+                       atomic_inc(&fsf_req->adapter->qdio_outb_full);
                        zfcp_qdio_undo_sbals(fsf_req);
                        return -EINVAL;
                }
@@ -307,7 +306,7 @@ static int zfcp_qdio_fill_sbals(struct zfcp_fsf_req *fsf_req,
 int zfcp_qdio_sbals_from_sg(struct zfcp_fsf_req *fsf_req, unsigned long sbtype,
                            struct scatterlist *sg, int max_sbals)
 {
-       volatile struct qdio_buffer_element *sbale;
+       struct qdio_buffer_element *sbale;
        int retval, bytes = 0;
 
        /* figure out last allowed SBAL */
@@ -344,10 +343,10 @@ int zfcp_qdio_send(struct zfcp_fsf_req *fsf_req)
        int first = fsf_req->sbal_first;
        int count = fsf_req->sbal_number;
        int retval, pci, pci_batch;
-       volatile struct qdio_buffer_element *sbale;
+       struct qdio_buffer_element *sbale;
 
        /* acknowledgements for transferred buffers */
-       pci_batch = req_q->pci_batch + count;
+       pci_batch = adapter->req_q_pci_batch + count;
        if (unlikely(pci_batch >= ZFCP_QDIO_PCI_INTERVAL)) {
                pci_batch %= ZFCP_QDIO_PCI_INTERVAL;
                pci = first + count - (pci_batch + 1);
@@ -367,7 +366,7 @@ int zfcp_qdio_send(struct zfcp_fsf_req *fsf_req)
        atomic_sub(count, &req_q->count);
        req_q->first += count;
        req_q->first %= QDIO_MAX_BUFFERS_PER_Q;
-       req_q->pci_batch = pci_batch;
+       adapter->req_q_pci_batch = pci_batch;
        return 0;
 }
 
@@ -418,14 +417,14 @@ void zfcp_qdio_close(struct zfcp_adapter *adapter)
        struct zfcp_qdio_queue *req_q;
        int first, count;
 
-       if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status))
+       if (!(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP))
                return;
 
        /* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */
        req_q = &adapter->req_q;
-       spin_lock_bh(&req_q->lock);
+       spin_lock_bh(&adapter->req_q_lock);
        atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
-       spin_unlock_bh(&req_q->lock);
+       spin_unlock_bh(&adapter->req_q_lock);
 
        qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR);
 
@@ -438,7 +437,7 @@ void zfcp_qdio_close(struct zfcp_adapter *adapter)
        }
        req_q->first = 0;
        atomic_set(&req_q->count, 0);
-       req_q->pci_batch = 0;
+       adapter->req_q_pci_batch = 0;
        adapter->resp_q.first = 0;
        atomic_set(&adapter->resp_q.count, 0);
 }
@@ -450,23 +449,17 @@ void zfcp_qdio_close(struct zfcp_adapter *adapter)
  */
 int zfcp_qdio_open(struct zfcp_adapter *adapter)
 {
-       volatile struct qdio_buffer_element *sbale;
+       struct qdio_buffer_element *sbale;
        int cc;
 
-       if (atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status))
+       if (atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP)
                return -EIO;
 
-       if (qdio_establish(&adapter->qdio_init_data)) {
-               dev_err(&adapter->ccw_device->dev,
-                        "Establish of QDIO queues failed.\n");
-               return -EIO;
-       }
+       if (qdio_establish(&adapter->qdio_init_data))
+               goto failed_establish;
 
-       if (qdio_activate(adapter->ccw_device)) {
-               dev_err(&adapter->ccw_device->dev,
-                        "Activate of QDIO queues failed.\n");
+       if (qdio_activate(adapter->ccw_device))
                goto failed_qdio;
-       }
 
        for (cc = 0; cc < QDIO_MAX_BUFFERS_PER_Q; cc++) {
                sbale = &(adapter->resp_q.sbal[cc]->element[0]);
@@ -476,20 +469,20 @@ int zfcp_qdio_open(struct zfcp_adapter *adapter)
        }
 
        if (do_QDIO(adapter->ccw_device, QDIO_FLAG_SYNC_INPUT, 0, 0,
-                    QDIO_MAX_BUFFERS_PER_Q)) {
-               dev_err(&adapter->ccw_device->dev,
-                        "Init of QDIO response queue failed.\n");
+                    QDIO_MAX_BUFFERS_PER_Q))
                goto failed_qdio;
-       }
 
        /* set index of first avalable SBALS / number of available SBALS */
        adapter->req_q.first = 0;
        atomic_set(&adapter->req_q.count, QDIO_MAX_BUFFERS_PER_Q);
-       adapter->req_q.pci_batch = 0;
+       adapter->req_q_pci_batch = 0;
 
        return 0;
 
 failed_qdio:
        qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR);
+failed_establish:
+       dev_err(&adapter->ccw_device->dev,
+               "Setting up the QDIO connection to the FCP adapter failed\n");
        return -EIO;
 }
index aeae56b00b4590e786935ff41bd4352c59b69871..ca8f85f3dad439f515e25b8e5b049a0edd3701ee 100644 (file)
@@ -21,20 +21,6 @@ char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *fcp_rsp_iu)
        return fcp_sns_info_ptr;
 }
 
-void zfcp_set_fcp_dl(struct fcp_cmnd_iu *fcp_cmd, fcp_dl_t fcp_dl)
-{
-       fcp_dl_t *fcp_dl_ptr;
-
-       /*
-        * fcp_dl_addr = start address of fcp_cmnd structure +
-        * size of fixed part + size of dynamically sized add_dcp_cdb field
-        * SEE FCP-2 documentation
-        */
-       fcp_dl_ptr = (fcp_dl_t *) ((unsigned char *) &fcp_cmd[1] +
-                                  (fcp_cmd->add_fcp_cdb_length << 2));
-       *fcp_dl_ptr = fcp_dl;
-}
-
 static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt)
 {
        struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata;
@@ -119,13 +105,17 @@ static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *adapter,
 {
        struct zfcp_port *port;
        struct zfcp_unit *unit;
+       int scsi_lun;
 
        list_for_each_entry(port, &adapter->port_list_head, list) {
                if (!port->rport || (id != port->rport->scsi_target_id))
                        continue;
-               list_for_each_entry(unit, &port->unit_list_head, list)
-                       if (lun == unit->scsi_lun)
+               list_for_each_entry(unit, &port->unit_list_head, list) {
+                       scsi_lun = scsilun_to_int(
+                               (struct scsi_lun *)&unit->fcp_lun);
+                       if (lun == scsi_lun)
                                return unit;
+               }
        }
 
        return NULL;
@@ -183,7 +173,6 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
                return retval;
        }
        fsf_req->data = NULL;
-       fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTING;
 
        /* don't access old fsf_req after releasing the abort_lock */
        write_unlock_irqrestore(&adapter->abort_lock, flags);
@@ -294,7 +283,8 @@ int zfcp_adapter_scsi_register(struct zfcp_adapter *adapter)
                                             sizeof (struct zfcp_adapter *));
        if (!adapter->scsi_host) {
                dev_err(&adapter->ccw_device->dev,
-                       "registration with SCSI stack failed.");
+                       "Registering the FCP device with the "
+                       "SCSI stack failed\n");
                return -EIO;
        }
 
@@ -312,7 +302,6 @@ int zfcp_adapter_scsi_register(struct zfcp_adapter *adapter)
                scsi_host_put(adapter->scsi_host);
                return -EIO;
        }
-       atomic_set_mask(ZFCP_STATUS_ADAPTER_REGISTERED, &adapter->status);
 
        return 0;
 }
@@ -336,7 +325,6 @@ void zfcp_adapter_scsi_unregister(struct zfcp_adapter *adapter)
        scsi_remove_host(shost);
        scsi_host_put(shost);
        adapter->scsi_host = NULL;
-       atomic_clear_mask(ZFCP_STATUS_ADAPTER_REGISTERED, &adapter->status);
 
        return;
 }
index 2e85c6c49e7dd7a03ab283cb073520aef6d7d85a..2809d789b55cbbed03e3425d607302a61a1569e7 100644 (file)
@@ -26,9 +26,9 @@ static ZFCP_DEV_ATTR(_feat, _name, S_IRUGO,                                  \
 ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, status, "0x%08x\n",
                 atomic_read(&adapter->status));
 ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, peer_wwnn, "0x%016llx\n",
-                adapter->peer_wwnn);
+                (unsigned long long) adapter->peer_wwnn);
 ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, peer_wwpn, "0x%016llx\n",
-                adapter->peer_wwpn);
+                (unsigned long long) adapter->peer_wwpn);
 ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, peer_d_id, "0x%06x\n",
                 adapter->peer_d_id);
 ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, card_version, "0x%04x\n",
@@ -135,8 +135,9 @@ static ssize_t zfcp_sysfs_port_remove_store(struct device *dev,
 {
        struct zfcp_adapter *adapter = dev_get_drvdata(dev);
        struct zfcp_port *port;
-       wwn_t wwpn;
+       u64 wwpn;
        int retval = 0;
+       LIST_HEAD(port_remove_lh);
 
        down(&zfcp_data.config_sema);
        if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_REMOVE) {
@@ -144,7 +145,7 @@ static ssize_t zfcp_sysfs_port_remove_store(struct device *dev,
                goto out;
        }
 
-       if (strict_strtoull(buf, 0, &wwpn)) {
+       if (strict_strtoull(buf, 0, (unsigned long long *) &wwpn)) {
                retval = -EINVAL;
                goto out;
        }
@@ -154,7 +155,7 @@ static ssize_t zfcp_sysfs_port_remove_store(struct device *dev,
        if (port && (atomic_read(&port->refcount) == 0)) {
                zfcp_port_get(port);
                atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
-               list_move(&port->list, &adapter->port_remove_lh);
+               list_move(&port->list, &port_remove_lh);
        } else
                port = NULL;
        write_unlock_irq(&zfcp_data.config_lock);
@@ -200,7 +201,7 @@ static ssize_t zfcp_sysfs_unit_add_store(struct device *dev,
 {
        struct zfcp_port *port = dev_get_drvdata(dev);
        struct zfcp_unit *unit;
-       fcp_lun_t fcp_lun;
+       u64 fcp_lun;
        int retval = -EINVAL;
 
        down(&zfcp_data.config_sema);
@@ -209,7 +210,7 @@ static ssize_t zfcp_sysfs_unit_add_store(struct device *dev,
                goto out;
        }
 
-       if (strict_strtoull(buf, 0, &fcp_lun))
+       if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun))
                goto out;
 
        unit = zfcp_unit_enqueue(port, fcp_lun);
@@ -233,8 +234,9 @@ static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev,
 {
        struct zfcp_port *port = dev_get_drvdata(dev);
        struct zfcp_unit *unit;
-       fcp_lun_t fcp_lun;
+       u64 fcp_lun;
        int retval = 0;
+       LIST_HEAD(unit_remove_lh);
 
        down(&zfcp_data.config_sema);
        if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE) {
@@ -242,7 +244,7 @@ static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev,
                goto out;
        }
 
-       if (strict_strtoull(buf, 0, &fcp_lun)) {
+       if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun)) {
                retval = -EINVAL;
                goto out;
        }
@@ -252,7 +254,7 @@ static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev,
        if (unit && (atomic_read(&unit->refcount) == 0)) {
                zfcp_unit_get(unit);
                atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status);
-               list_move(&unit->list, &port->unit_remove_lh);
+               list_move(&unit->list, &unit_remove_lh);
        } else
                unit = NULL;
 
@@ -273,22 +275,7 @@ out:
 }
 static DEVICE_ATTR(unit_remove, S_IWUSR, NULL, zfcp_sysfs_unit_remove_store);
 
-static struct attribute *zfcp_port_ns_attrs[] = {
-       &dev_attr_port_failed.attr,
-       &dev_attr_port_in_recovery.attr,
-       &dev_attr_port_status.attr,
-       &dev_attr_port_access_denied.attr,
-       NULL
-};
-
-/**
- * zfcp_sysfs_ns_port_attrs - sysfs attributes for nameserver
- */
-struct attribute_group zfcp_sysfs_ns_port_attrs = {
-       .attrs = zfcp_port_ns_attrs,
-};
-
-static struct attribute *zfcp_port_no_ns_attrs[] = {
+static struct attribute *zfcp_port_attrs[] = {
        &dev_attr_unit_add.attr,
        &dev_attr_unit_remove.attr,
        &dev_attr_port_failed.attr,
@@ -302,7 +289,7 @@ static struct attribute *zfcp_port_no_ns_attrs[] = {
  * zfcp_sysfs_port_attrs - sysfs attributes for all other ports
  */
 struct attribute_group zfcp_sysfs_port_attrs = {
-       .attrs = zfcp_port_no_ns_attrs,
+       .attrs = zfcp_port_attrs,
 };
 
 static struct attribute *zfcp_unit_attrs[] = {
@@ -395,8 +382,10 @@ static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_scsi_##_name##_show, NULL);
 
 ZFCP_DEFINE_SCSI_ATTR(hba_id, "%s\n",
        unit->port->adapter->ccw_device->dev.bus_id);
-ZFCP_DEFINE_SCSI_ATTR(wwpn, "0x%016llx\n", unit->port->wwpn);
-ZFCP_DEFINE_SCSI_ATTR(fcp_lun, "0x%016llx\n", unit->fcp_lun);
+ZFCP_DEFINE_SCSI_ATTR(wwpn, "0x%016llx\n",
+                     (unsigned long long) unit->port->wwpn);
+ZFCP_DEFINE_SCSI_ATTR(fcp_lun, "0x%016llx\n",
+                     (unsigned long long) unit->fcp_lun);
 
 struct device_attribute *zfcp_sysfs_sdev_attrs[] = {
        &dev_attr_fcp_lun,
@@ -487,10 +476,23 @@ ZFCP_SHOST_ATTR(megabytes, "%llu %llu\n",
 ZFCP_SHOST_ATTR(seconds_active, "%llu\n",
                (unsigned long long) stat_info.seconds_act);
 
+static ssize_t zfcp_sysfs_adapter_q_full_show(struct device *dev,
+                                             struct device_attribute *attr,
+                                             char *buf)
+{
+       struct Scsi_Host *scsi_host = class_to_shost(dev);
+       struct zfcp_adapter *adapter =
+               (struct zfcp_adapter *) scsi_host->hostdata[0];
+
+       return sprintf(buf, "%d\n", atomic_read(&adapter->qdio_outb_full));
+}
+static DEVICE_ATTR(queue_full, S_IRUGO, zfcp_sysfs_adapter_q_full_show, NULL);
+
 struct device_attribute *zfcp_sysfs_shost_attrs[] = {
        &dev_attr_utilization,
        &dev_attr_requests,
        &dev_attr_megabytes,
        &dev_attr_seconds_active,
+       &dev_attr_queue_full,
        NULL
 };
index 4e0322b1c1ea07301f180621912cd785d8882402..d3b211af4e1cd259a4d38bec0193a7792090d991 100644 (file)
@@ -1325,14 +1325,6 @@ config SCSI_QLOGIC_FAS
          To compile this driver as a module, choose M here: the
          module will be called qlogicfas.
 
-config SCSI_QLOGIC_FC_FIRMWARE
-       bool "Include loadable firmware in driver"
-       depends on SCSI_QLOGIC_FC
-       help
-         Say Y to include ISP2X00 Fabric Initiator/Target Firmware, with
-         expanded LUN addressing and FcTape (FCP-2) support, in the
-         qlogicfc driver. This is required on some platforms.
-
 config SCSI_QLOGIC_1280
        tristate "Qlogic QLA 1240/1x80/1x160 SCSI support"
        depends on PCI && SCSI
index aa4e77c252735c593e523ae4a9f516045b674733..8abfd06b5a72c19a766edd41706a9ec0b00a802b 100644 (file)
@@ -1139,7 +1139,7 @@ static struct aac_srb * aac_scsi_common(struct fib * fib, struct scsi_cmnd * cmd
        srbcmd->id       = cpu_to_le32(scmd_id(cmd));
        srbcmd->lun      = cpu_to_le32(cmd->device->lun);
        srbcmd->flags    = cpu_to_le32(flag);
-       timeout = cmd->timeout_per_command/HZ;
+       timeout = cmd->request->timeout/HZ;
        if (timeout == 0)
                timeout = 1;
        srbcmd->timeout  = cpu_to_le32(timeout);  // timeout in seconds
index ef693e8412e9d14c1393ddf10478221b0cbacbf1..8f45570a8a01ca3d1943117e944e57d08d407789 100644 (file)
@@ -84,7 +84,7 @@ struct clariion_dh_data {
        /*
         * I/O buffer for both MODE_SELECT and INQUIRY commands.
         */
-       char buffer[CLARIION_BUFFER_SIZE];
+       unsigned char buffer[CLARIION_BUFFER_SIZE];
        /*
         * SCSI sense buffer for commands -- assumes serial issuance
         * and completion sequence of all commands for same multipath.
@@ -176,7 +176,7 @@ static int parse_sp_info_reply(struct scsi_device *sdev,
                err = SCSI_DH_DEV_TEMP_BUSY;
                goto out;
        }
-       if (csdev->buffer[4] < 0 || csdev->buffer[4] > 2) {
+       if (csdev->buffer[4] > 2) {
                /* Invalid buffer format */
                sdev_printk(KERN_NOTICE, sdev,
                            "%s: invalid VPD page 0xC0 format\n",
@@ -278,7 +278,6 @@ static struct request *get_req(struct scsi_device *sdev, int cmd,
                return NULL;
        }
 
-       memset(rq->cmd, 0, BLK_MAX_CDB);
        rq->cmd_len = COMMAND_SIZE(cmd);
        rq->cmd[0] = cmd;
 
index a6a4ef3ad51c01e83421d22a11bafbc0f9eb87aa..5e93c88ad66b95e871b6d01236f9403a3269d048 100644 (file)
@@ -114,7 +114,6 @@ static int hp_sw_tur(struct scsi_device *sdev, struct hp_sw_dh_data *h)
        req->cmd_type = REQ_TYPE_BLOCK_PC;
        req->cmd_flags |= REQ_FAILFAST;
        req->cmd_len = COMMAND_SIZE(TEST_UNIT_READY);
-       memset(req->cmd, 0, MAX_COMMAND_SIZE);
        req->cmd[0] = TEST_UNIT_READY;
        req->timeout = HP_SW_TIMEOUT;
        req->sense = h->sense;
@@ -207,7 +206,6 @@ static int hp_sw_start_stop(struct scsi_device *sdev, struct hp_sw_dh_data *h)
        req->cmd_type = REQ_TYPE_BLOCK_PC;
        req->cmd_flags |= REQ_FAILFAST;
        req->cmd_len = COMMAND_SIZE(START_STOP);
-       memset(req->cmd, 0, MAX_COMMAND_SIZE);
        req->cmd[0] = START_STOP;
        req->cmd[4] = 1;        /* Start spin cycle */
        req->timeout = HP_SW_TIMEOUT;
index 6e2f130d56deb7b89b0852c94b788e5e7e7544a0..50bf95f3b5c456cb7118583ed297b48b3782ed57 100644 (file)
@@ -225,8 +225,6 @@ static struct request *get_rdac_req(struct scsi_device *sdev,
                return NULL;
        }
 
-       memset(rq->cmd, 0, BLK_MAX_CDB);
-
        rq->cmd_type = REQ_TYPE_BLOCK_PC;
        rq->cmd_flags |= REQ_FAILFAST | REQ_NOMERGE;
        rq->retries = RDAC_RETRIES;
@@ -590,6 +588,8 @@ static const struct scsi_dh_devlist rdac_dev_list[] = {
        {"STK", "OPENstorage D280"},
        {"SUN", "CSM200_R"},
        {"SUN", "LCSM100_F"},
+       {"DELL", "MD3000"},
+       {"DELL", "MD3000i"},
        {NULL, NULL},
 };
 
index 822d5214692bfe3663b5acb8987ffec5a0ec0cd5..c387c15a21282e250b6291ac9872ba91877a1dc2 100644 (file)
@@ -464,7 +464,6 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd,
 
     /* use request field to save the ptr. to completion struct. */
     scp->request = (struct request *)&wait;
-    scp->timeout_per_command = timeout*HZ;
     scp->cmd_len = 12;
     scp->cmnd = cmnd;
     cmndinfo.priority = IOCTL_PRI;
@@ -1995,23 +1994,12 @@ static void gdth_putq(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar priority)
     register Scsi_Cmnd *pscp;
     register Scsi_Cmnd *nscp;
     ulong flags;
-    unchar b, t;
 
     TRACE(("gdth_putq() priority %d\n",priority));
     spin_lock_irqsave(&ha->smp_lock, flags);
 
-    if (!cmndinfo->internal_command) {
+    if (!cmndinfo->internal_command)
         cmndinfo->priority = priority;
-        b = scp->device->channel;
-        t = scp->device->id;
-        if (priority >= DEFAULT_PRI) {
-            if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) ||
-                (b==ha->virt_bus && t<MAX_HDRIVES && ha->hdr[t].lock)) {
-                TRACE2(("gdth_putq(): locked IO ->update_timeout()\n"));
-                cmndinfo->timeout = gdth_update_timeout(scp, 0);
-            }
-        }
-    }
 
     if (ha->req_first==NULL) {
         ha->req_first = scp;                    /* queue was empty */
@@ -3899,6 +3887,39 @@ static const char *gdth_info(struct Scsi_Host *shp)
     return ((const char *)ha->binfo.type_string);
 }
 
+static enum blk_eh_timer_return gdth_timed_out(struct scsi_cmnd *scp)
+{
+       gdth_ha_str *ha = shost_priv(scp->device->host);
+       struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp);
+       unchar b, t;
+       ulong flags;
+       enum blk_eh_timer_return retval = BLK_EH_NOT_HANDLED;
+
+       TRACE(("%s() cmd 0x%x\n", scp->cmnd[0], __func__));
+       b = scp->device->channel;
+       t = scp->device->id;
+
+       /*
+        * We don't really honor the command timeout, but we try to
+        * honor 6 times of the actual command timeout! So reset the
+        * timer if this is less than 6th timeout on this command!
+        */
+       if (++cmndinfo->timeout_count < 6)
+               retval = BLK_EH_RESET_TIMER;
+
+       /* Reset the timeout if it is locked IO */
+       spin_lock_irqsave(&ha->smp_lock, flags);
+       if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha, b)].lock) ||
+           (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) {
+               TRACE2(("%s(): locked IO, reset timeout\n", __func__));
+               retval = BLK_EH_RESET_TIMER;
+       }
+       spin_unlock_irqrestore(&ha->smp_lock, flags);
+
+       return retval;
+}
+
+
 static int gdth_eh_bus_reset(Scsi_Cmnd *scp)
 {
     gdth_ha_str *ha = shost_priv(scp->device->host);
@@ -3992,7 +4013,7 @@ static int gdth_queuecommand(struct scsi_cmnd *scp,
     BUG_ON(!cmndinfo);
 
     scp->scsi_done = done;
-    gdth_update_timeout(scp, scp->timeout_per_command * 6);
+    cmndinfo->timeout_count = 0;
     cmndinfo->priority = DEFAULT_PRI;
 
     return __gdth_queuecommand(ha, scp, cmndinfo);
@@ -4096,12 +4117,10 @@ static int ioc_lockdrv(void __user *arg)
             ha->hdr[j].lock = 1;
             spin_unlock_irqrestore(&ha->smp_lock, flags);
             gdth_wait_completion(ha, ha->bus_cnt, j);
-            gdth_stop_timeout(ha, ha->bus_cnt, j);
         } else {
             spin_lock_irqsave(&ha->smp_lock, flags);
             ha->hdr[j].lock = 0;
             spin_unlock_irqrestore(&ha->smp_lock, flags);
-            gdth_start_timeout(ha, ha->bus_cnt, j);
             gdth_next(ha);
         }
     } 
@@ -4539,18 +4558,14 @@ static int gdth_ioctl(struct inode *inode, struct file *filep,
                 spin_lock_irqsave(&ha->smp_lock, flags);
                 ha->raw[i].lock = 1;
                 spin_unlock_irqrestore(&ha->smp_lock, flags);
-                for (j = 0; j < ha->tid_cnt; ++j) {
+               for (j = 0; j < ha->tid_cnt; ++j)
                     gdth_wait_completion(ha, i, j);
-                    gdth_stop_timeout(ha, i, j);
-                }
             } else {
                 spin_lock_irqsave(&ha->smp_lock, flags);
                 ha->raw[i].lock = 0;
                 spin_unlock_irqrestore(&ha->smp_lock, flags);
-                for (j = 0; j < ha->tid_cnt; ++j) {
-                    gdth_start_timeout(ha, i, j);
+               for (j = 0; j < ha->tid_cnt; ++j)
                     gdth_next(ha);
-                }
             }
         } 
         break;
@@ -4644,6 +4659,7 @@ static struct scsi_host_template gdth_template = {
         .slave_configure        = gdth_slave_configure,
         .bios_param             = gdth_bios_param,
         .proc_info              = gdth_proc_info,
+       .eh_timed_out           = gdth_timed_out,
         .proc_name              = "gdth",
         .can_queue              = GDTH_MAXCMDS,
         .this_id                = -1,
index ca92476727cfae82b258107405023f9a98baf661..1646444e9bd58894ef8af3cadcfe3b2bd7287be0 100644 (file)
@@ -916,7 +916,7 @@ typedef struct {
         gdth_cmd_str *internal_cmd_str;         /* crier for internal messages*/
         dma_addr_t sense_paddr;                 /* sense dma-addr */
         unchar priority;
-        int timeout;
+       int timeout_count;                      /* # of timeout calls */
         volatile int wait_for_completion;
         ushort status;
         ulong32 info;
index ce0228e26aec24fe070acb47b93451b0c377af23..59349a316e137facdd9b7f76b412ac14f23190ae 100644 (file)
@@ -748,69 +748,3 @@ static void gdth_wait_completion(gdth_ha_str *ha, int busnum, int id)
     }
     spin_unlock_irqrestore(&ha->smp_lock, flags);
 }
-
-static void gdth_stop_timeout(gdth_ha_str *ha, int busnum, int id)
-{
-    ulong flags;
-    Scsi_Cmnd *scp;
-    unchar b, t;
-
-    spin_lock_irqsave(&ha->smp_lock, flags);
-
-    for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) {
-        struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp);
-        if (!cmndinfo->internal_command) {
-            b = scp->device->channel;
-            t = scp->device->id;
-            if (t == (unchar)id && b == (unchar)busnum) {
-                TRACE2(("gdth_stop_timeout(): update_timeout()\n"));
-                cmndinfo->timeout = gdth_update_timeout(scp, 0);
-            }
-        }
-    }
-    spin_unlock_irqrestore(&ha->smp_lock, flags);
-}
-
-static void gdth_start_timeout(gdth_ha_str *ha, int busnum, int id)
-{
-    ulong flags;
-    Scsi_Cmnd *scp;
-    unchar b, t;
-
-    spin_lock_irqsave(&ha->smp_lock, flags);
-
-    for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) {
-        struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp);
-        if (!cmndinfo->internal_command) {
-            b = scp->device->channel;
-            t = scp->device->id;
-            if (t == (unchar)id && b == (unchar)busnum) {
-                TRACE2(("gdth_start_timeout(): update_timeout()\n"));
-                gdth_update_timeout(scp, cmndinfo->timeout);
-            }
-        }
-    }
-    spin_unlock_irqrestore(&ha->smp_lock, flags);
-}
-
-static int gdth_update_timeout(Scsi_Cmnd *scp, int timeout)
-{
-    int oldto;
-
-    oldto = scp->timeout_per_command;
-    scp->timeout_per_command = timeout;
-
-    if (timeout == 0) {
-        del_timer(&scp->eh_timeout);
-        scp->eh_timeout.data = (unsigned long) NULL;
-        scp->eh_timeout.expires = 0;
-    } else {
-        if (scp->eh_timeout.data != (unsigned long) NULL) 
-            del_timer(&scp->eh_timeout);
-        scp->eh_timeout.data = (unsigned long) scp;
-        scp->eh_timeout.expires = jiffies + timeout;
-        add_timer(&scp->eh_timeout);
-    }
-
-    return oldto;
-}
index 45e6fdacf36e39d06eee15ba10e7c12f396673a5..9b900cc9ebe898dca7bb4ce12fd35851a6bb21bc 100644 (file)
@@ -20,9 +20,6 @@ static char *gdth_ioctl_alloc(gdth_ha_str *ha, int size, int scratch,
                               ulong64 *paddr);
 static void gdth_ioctl_free(gdth_ha_str *ha, int size, char *buf, ulong64 paddr);
 static void gdth_wait_completion(gdth_ha_str *ha, int busnum, int id);
-static void gdth_stop_timeout(gdth_ha_str *ha, int busnum, int id);
-static void gdth_start_timeout(gdth_ha_str *ha, int busnum, int id);
-static int gdth_update_timeout(Scsi_Cmnd *scp, int timeout);
 
 #endif
 
index fed0b02ebc1d35ecba7c19b534956edf939eb7a6..3fdbb13e80a8ffa95a822ef30eb12a5cef7a5082 100644 (file)
@@ -464,7 +464,7 @@ static int __scsi_host_match(struct device *dev, void *data)
 struct Scsi_Host *scsi_host_lookup(unsigned short hostnum)
 {
        struct device *cdev;
-       struct Scsi_Host *shost = ERR_PTR(-ENXIO);
+       struct Scsi_Host *shost = NULL;
 
        cdev = class_find_device(&shost_class, NULL, &hostnum,
                                 __scsi_host_match);
index 7b1502c0ab6e5e049a66058be068478ebc5886ec..87e09f35d3d4cb2bb50de263098d0a4c9ea2b66b 100644 (file)
@@ -756,7 +756,7 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd,
        init_event_struct(evt_struct,
                          handle_cmd_rsp,
                          VIOSRP_SRP_FORMAT,
-                         cmnd->timeout_per_command/HZ);
+                         cmnd->request->timeout/HZ);
 
        evt_struct->cmnd = cmnd;
        evt_struct->cmnd_done = done;
index 461331d3dc45f041fd23bb8c02cc0f87b6737fe8..81c16cba5417ff76a0f11006193e2747438e6154 100644 (file)
@@ -612,7 +612,7 @@ static int idescsi_queue (struct scsi_cmnd *cmd,
        pc->req_xfer = pc->buf_size = scsi_bufflen(cmd);
        pc->scsi_cmd = cmd;
        pc->done = done;
-       pc->timeout = jiffies + cmd->timeout_per_command;
+       pc->timeout = jiffies + cmd->request->timeout;
 
        if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) {
                printk ("ide-scsi: %s: que %lu, cmd = ", drive->name, cmd->serial_number);
index e7a3a655442562186328d81df9d81be9f744f5f6..d30eb7ba018e6dde266ac53253b95c8687dde8e8 100644 (file)
@@ -3670,7 +3670,8 @@ static int ipr_slave_configure(struct scsi_device *sdev)
                        sdev->no_uld_attach = 1;
                }
                if (ipr_is_vset_device(res)) {
-                       sdev->timeout = IPR_VSET_RW_TIMEOUT;
+                       blk_queue_rq_timeout(sdev->request_queue,
+                                            IPR_VSET_RW_TIMEOUT);
                        blk_queue_max_sectors(sdev->request_queue, IPR_VSET_MAX_SECTORS);
                }
                if (ipr_is_vset_device(res) || ipr_is_scsi_disk(res))
index bc9e6ddf41df237ec5dd030950d42619174b883e..ef683f0d2b5a94c5f66626a49f3b954e9c0862ab 100644 (file)
@@ -3818,7 +3818,7 @@ ips_send_cmd(ips_ha_t * ha, ips_scb_t * scb)
                scb->cmd.dcdb.segment_4G = 0;
                scb->cmd.dcdb.enhanced_sg = 0;
 
-               TimeOut = scb->scsi_cmd->timeout_per_command;
+               TimeOut = scb->scsi_cmd->request->timeout;
 
                if (ha->subsys->param[4] & 0x00100000) {        /* If NEW Tape DCDB is Supported */
                        if (!scb->sg_len) {
index 299e075a7b34295f6a8ea8721270a329913a3244..da7b67d30d9a336d4d3d6960f0604c043d8f13f9 100644 (file)
@@ -1456,7 +1456,7 @@ static void fail_all_commands(struct iscsi_conn *conn, unsigned lun,
                if (lun == task->sc->device->lun || lun == -1) {
                        debug_scsi("failing in progress sc %p itt 0x%x\n",
                                   task->sc, task->itt);
-                       fail_command(conn, task, DID_BUS_BUSY << 16);
+                       fail_command(conn, task, error << 16);
                }
        }
 }
@@ -1476,12 +1476,12 @@ static void iscsi_start_tx(struct iscsi_conn *conn)
                scsi_queue_work(conn->session->host, &conn->xmitwork);
 }
 
-static enum scsi_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd)
+static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd)
 {
        struct iscsi_cls_session *cls_session;
        struct iscsi_session *session;
        struct iscsi_conn *conn;
-       enum scsi_eh_timer_return rc = EH_NOT_HANDLED;
+       enum blk_eh_timer_return rc = BLK_EH_NOT_HANDLED;
 
        cls_session = starget_to_session(scsi_target(scmd->device));
        session = cls_session->dd_data;
@@ -1494,14 +1494,14 @@ static enum scsi_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd)
                 * We are probably in the middle of iscsi recovery so let
                 * that complete and handle the error.
                 */
-               rc = EH_RESET_TIMER;
+               rc = BLK_EH_RESET_TIMER;
                goto done;
        }
 
        conn = session->leadconn;
        if (!conn) {
                /* In the middle of shuting down */
-               rc = EH_RESET_TIMER;
+               rc = BLK_EH_RESET_TIMER;
                goto done;
        }
 
@@ -1513,20 +1513,21 @@ static enum scsi_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd)
         */
        if (time_before_eq(conn->last_recv + (conn->recv_timeout * HZ) +
                            (conn->ping_timeout * HZ), jiffies))
-               rc = EH_RESET_TIMER;
+               rc = BLK_EH_RESET_TIMER;
        /*
         * if we are about to check the transport then give the command
         * more time
         */
        if (time_before_eq(conn->last_recv + (conn->recv_timeout * HZ),
                           jiffies))
-               rc = EH_RESET_TIMER;
+               rc = BLK_EH_RESET_TIMER;
        /* if in the middle of checking the transport then give us more time */
        if (conn->ping_task)
-               rc = EH_RESET_TIMER;
+               rc = BLK_EH_RESET_TIMER;
 done:
        spin_unlock(&session->lock);
-       debug_scsi("return %s\n", rc == EH_RESET_TIMER ? "timer reset" : "nh");
+       debug_scsi("return %s\n", rc == BLK_EH_RESET_TIMER ?
+                                       "timer reset" : "nh");
        return rc;
 }
 
index 48ee8c7f5bdd270351bcdf0dae895e0ae572a3f2..e15501170698a19957d22f92c6fbc2e3e89ac0c6 100644 (file)
@@ -294,10 +294,10 @@ static void sas_ata_post_internal(struct ata_queued_cmd *qc)
        }
 }
 
-static int sas_ata_scr_write(struct ata_port *ap, unsigned int sc_reg_in,
+static int sas_ata_scr_write(struct ata_link *link, unsigned int sc_reg_in,
                              u32 val)
 {
-       struct domain_device *dev = ap->private_data;
+       struct domain_device *dev = link->ap->private_data;
 
        SAS_DPRINTK("STUB %s\n", __func__);
        switch (sc_reg_in) {
@@ -319,10 +319,10 @@ static int sas_ata_scr_write(struct ata_port *ap, unsigned int sc_reg_in,
        return 0;
 }
 
-static int sas_ata_scr_read(struct ata_port *ap, unsigned int sc_reg_in,
+static int sas_ata_scr_read(struct ata_link *link, unsigned int sc_reg_in,
                            u32 *val)
 {
-       struct domain_device *dev = ap->private_data;
+       struct domain_device *dev = link->ap->private_data;
 
        SAS_DPRINTK("STUB %s\n", __func__);
        switch (sc_reg_in) {
@@ -398,7 +398,7 @@ void sas_ata_task_abort(struct sas_task *task)
 
        /* Bounce SCSI-initiated commands to the SCSI EH */
        if (qc->scsicmd) {
-               scsi_req_abort_cmd(qc->scsicmd);
+               blk_abort_request(qc->scsicmd->request);
                scsi_schedule_eh(qc->scsicmd->device->host);
                return;
        }
index b4f9368f116ac2002ac07741fd2f2ddc3b2ef33e..0001374bd6b251164d69d7fdf3b7ced78e4b5901 100644 (file)
@@ -55,7 +55,7 @@ void sas_unregister_phys(struct sas_ha_struct *sas_ha);
 int  sas_register_ports(struct sas_ha_struct *sas_ha);
 void sas_unregister_ports(struct sas_ha_struct *sas_ha);
 
-enum scsi_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *);
+enum blk_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *);
 
 int  sas_init_queue(struct sas_ha_struct *sas_ha);
 int  sas_init_events(struct sas_ha_struct *sas_ha);
index a8e3ef309070ae9e0da26381668e0bd847b68e0b..744838780ada207964f5b8ffbc4749d6c098ae57 100644 (file)
@@ -673,43 +673,43 @@ out:
        return;
 }
 
-enum scsi_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd)
+enum blk_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd)
 {
        struct sas_task *task = TO_SAS_TASK(cmd);
        unsigned long flags;
 
        if (!task) {
-               cmd->timeout_per_command /= 2;
+               cmd->request->timeout /= 2;
                SAS_DPRINTK("command 0x%p, task 0x%p, gone: %s\n",
-                           cmd, task, (cmd->timeout_per_command ?
-                           "EH_RESET_TIMER" : "EH_NOT_HANDLED"));
-               if (!cmd->timeout_per_command)
-                       return EH_NOT_HANDLED;
-               return EH_RESET_TIMER;
+                           cmd, task, (cmd->request->timeout ?
+                           "BLK_EH_RESET_TIMER" : "BLK_EH_NOT_HANDLED"));
+               if (!cmd->request->timeout)
+                       return BLK_EH_NOT_HANDLED;
+               return BLK_EH_RESET_TIMER;
        }
 
        spin_lock_irqsave(&task->task_state_lock, flags);
        BUG_ON(task->task_state_flags & SAS_TASK_STATE_ABORTED);
        if (task->task_state_flags & SAS_TASK_STATE_DONE) {
                spin_unlock_irqrestore(&task->task_state_lock, flags);
-               SAS_DPRINTK("command 0x%p, task 0x%p, timed out: EH_HANDLED\n",
-                           cmd, task);
-               return EH_HANDLED;
+               SAS_DPRINTK("command 0x%p, task 0x%p, timed out: "
+                           "BLK_EH_HANDLED\n", cmd, task);
+               return BLK_EH_HANDLED;
        }
        if (!(task->task_state_flags & SAS_TASK_AT_INITIATOR)) {
                spin_unlock_irqrestore(&task->task_state_lock, flags);
                SAS_DPRINTK("command 0x%p, task 0x%p, not at initiator: "
-                           "EH_RESET_TIMER\n",
+                           "BLK_EH_RESET_TIMER\n",
                            cmd, task);
-               return EH_RESET_TIMER;
+               return BLK_EH_RESET_TIMER;
        }
        task->task_state_flags |= SAS_TASK_STATE_ABORTED;
        spin_unlock_irqrestore(&task->task_state_lock, flags);
 
-       SAS_DPRINTK("command 0x%p, task 0x%p, timed out: EH_NOT_HANDLED\n",
+       SAS_DPRINTK("command 0x%p, task 0x%p, timed out: BLK_EH_NOT_HANDLED\n",
                    cmd, task);
 
-       return EH_NOT_HANDLED;
+       return BLK_EH_NOT_HANDLED;
 }
 
 int sas_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
@@ -1039,7 +1039,7 @@ void sas_task_abort(struct sas_task *task)
                return;
        }
 
-       scsi_req_abort_cmd(sc);
+       blk_abort_request(sc->request);
        scsi_schedule_eh(sc->device->host);
 }
 
index 97b763378e7dca9e8de4678eeb013f25ac2da185..afe1de99876319ba40d7c28a884458a3bff1b91e 100644 (file)
@@ -1167,7 +1167,7 @@ static int megasas_generic_reset(struct scsi_cmnd *scmd)
  * cmd has not been completed within the timeout period.
  */
 static enum
-scsi_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)
+blk_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)
 {
        struct megasas_cmd *cmd = (struct megasas_cmd *)scmd->SCp.ptr;
        struct megasas_instance *instance;
@@ -1175,7 +1175,7 @@ scsi_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)
 
        if (time_after(jiffies, scmd->jiffies_at_alloc +
                                (MEGASAS_DEFAULT_CMD_TIMEOUT * 2) * HZ)) {
-               return EH_NOT_HANDLED;
+               return BLK_EH_NOT_HANDLED;
        }
 
        instance = cmd->instance;
@@ -1189,7 +1189,7 @@ scsi_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)
 
                spin_unlock_irqrestore(instance->host->host_lock, flags);
        }
-       return EH_RESET_TIMER;
+       return BLK_EH_RESET_TIMER;
 }
 
 /**
index c57c94c0ffd237f1d39b0cf6ea164e737ac11643..3b7240e40819cb98a0024f031b964e306f17f990 100644 (file)
@@ -4170,8 +4170,8 @@ static int ncr_queue_command (struct ncb *np, struct scsi_cmnd *cmd)
        **
        **----------------------------------------------------
        */
-       if (np->settle_time && cmd->timeout_per_command >= HZ) {
-               u_long tlimit = jiffies + cmd->timeout_per_command - HZ;
+       if (np->settle_time && cmd->request->timeout >= HZ) {
+               u_long tlimit = jiffies + cmd->request->timeout - HZ;
                if (time_after(np->settle_time, tlimit))
                        np->settle_time = tlimit;
        }
index 37f9ba0cd798cf975a0139e5bf1fae99f5508923..b6cd12b2e9963468e32d00472ae3d0fd8a7d41bb 100644 (file)
@@ -2845,7 +2845,7 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
        memset(((char *)pkt + 8), 0, (REQUEST_ENTRY_SIZE - 8));
 
        /* Set ISP command timeout. */
-       pkt->timeout = cpu_to_le16(cmd->timeout_per_command/HZ);
+       pkt->timeout = cpu_to_le16(cmd->request->timeout/HZ);
 
        /* Set device target ID and LUN */
        pkt->lun = SCSI_LUN_32(cmd);
@@ -3114,7 +3114,7 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
        memset(((char *)pkt + 8), 0, (REQUEST_ENTRY_SIZE - 8));
 
        /* Set ISP command timeout. */
-       pkt->timeout = cpu_to_le16(cmd->timeout_per_command/HZ);
+       pkt->timeout = cpu_to_le16(cmd->request->timeout/HZ);
 
        /* Set device target ID and LUN */
        pkt->lun = SCSI_LUN_32(cmd);
index 45e7dcb4b34d8b276edae17cf56a13c749317fa3..0ddfe7106b3bd1cc270849d76e2d7b8a9071e296 100644 (file)
@@ -292,10 +292,11 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj,
                valid = 0;
                if (ha->optrom_size == OPTROM_SIZE_2300 && start == 0)
                        valid = 1;
-               else if (start == (FA_BOOT_CODE_ADDR*4) ||
-                   start == (FA_RISC_CODE_ADDR*4))
+               else if (start == (ha->flt_region_boot * 4) ||
+                   start == (ha->flt_region_fw * 4))
                        valid = 1;
-               else if (IS_QLA25XX(ha) && start == (FA_VPD_NVRAM_ADDR*4))
+               else if (IS_QLA25XX(ha) &&
+                   start == (ha->flt_region_vpd_nvram * 4))
                    valid = 1;
                if (!valid) {
                        qla_printk(KERN_WARNING, ha,
@@ -1065,6 +1066,8 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
                pfc_host_stat->dumped_frames = stats->dumped_frames;
                pfc_host_stat->nos_count = stats->nos_rcvd;
        }
+       pfc_host_stat->fcp_input_megabytes = ha->qla_stats.input_bytes >> 20;
+       pfc_host_stat->fcp_output_megabytes = ha->qla_stats.output_bytes >> 20;
 
 done_free:
         dma_pool_free(ha->s_dma_pool, stats, stats_dma);
index 94a720eabfd83cc491601ba7b53d5bfef82f4ae2..83c819216771a5c9c10d886789e3fa9350d75cc0 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/firmware.h>
 #include <linux/aer.h>
 #include <linux/mutex.h>
-#include <linux/semaphore.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
@@ -2157,6 +2156,8 @@ struct qla_chip_state_84xx {
 
 struct qla_statistics {
        uint32_t total_isp_aborts;
+       uint64_t input_bytes;
+       uint64_t output_bytes;
 };
 
 /*
@@ -2238,6 +2239,7 @@ typedef struct scsi_qla_host {
 #define FCPORT_UPDATE_NEEDED   27
 #define VP_DPC_NEEDED          28      /* wake up for VP dpc handling */
 #define UNLOADING              29
+#define NPIV_CONFIG_NEEDED     30
 
        uint32_t        device_flags;
 #define DFLG_LOCAL_DEVICES             BIT_0
@@ -2507,7 +2509,6 @@ typedef struct scsi_qla_host {
        uint64_t        fce_wr, fce_rd;
        struct mutex    fce_mutex;
 
-       uint32_t        hw_event_start;
        uint32_t        hw_event_ptr;
        uint32_t        hw_event_pause_errors;
 
@@ -2553,6 +2554,14 @@ typedef struct scsi_qla_host {
        uint32_t        fdt_unprotect_sec_cmd;
        uint32_t        fdt_protect_sec_cmd;
 
+       uint32_t        flt_region_flt;
+       uint32_t        flt_region_fdt;
+       uint32_t        flt_region_boot;
+       uint32_t        flt_region_fw;
+       uint32_t        flt_region_vpd_nvram;
+       uint32_t        flt_region_hw_event;
+       uint32_t        flt_region_npiv_conf;
+
        /* Needed for BEACON */
        uint16_t        beacon_blink_led;
        uint8_t         beacon_color_state;
index cf194517400d4d8f76f34dd29319a3045124e670..d1d14202575a8760a1308e02758f4de15d56a155 100644 (file)
@@ -789,14 +789,23 @@ struct device_reg_24xx {
 #define FA_RISC_CODE_ADDR      0x20000
 #define FA_RISC_CODE_SEGMENTS  2
 
+#define FA_FLASH_DESCR_ADDR_24 0x11000
+#define FA_FLASH_LAYOUT_ADDR_24        0x11400
+#define FA_NPIV_CONF0_ADDR_24  0x16000
+#define FA_NPIV_CONF1_ADDR_24  0x17000
+
 #define FA_FW_AREA_ADDR                0x40000
 #define FA_VPD_NVRAM_ADDR      0x48000
 #define FA_FEATURE_ADDR                0x4C000
 #define FA_FLASH_DESCR_ADDR    0x50000
+#define FA_FLASH_LAYOUT_ADDR   0x50400
 #define FA_HW_EVENT0_ADDR      0x54000
-#define FA_HW_EVENT1_ADDR      0x54200
+#define FA_HW_EVENT1_ADDR      0x54400
 #define FA_HW_EVENT_SIZE       0x200
 #define FA_HW_EVENT_ENTRY_SIZE 4
+#define FA_NPIV_CONF0_ADDR     0x5C000
+#define FA_NPIV_CONF1_ADDR     0x5D000
+
 /*
  * Flash Error Log Event Codes.
  */
@@ -806,10 +815,6 @@ struct device_reg_24xx {
 #define HW_EVENT_NVRAM_CHKSUM_ERR      0xF023
 #define HW_EVENT_FLASH_FW_ERR  0xF024
 
-#define FA_BOOT_LOG_ADDR       0x58000
-#define FA_FW_DUMP0_ADDR       0x60000
-#define FA_FW_DUMP1_ADDR       0x70000
-
        uint32_t flash_data;            /* Flash/NVRAM BIOS data. */
 
        uint32_t ctrl_status;           /* Control/Status. */
@@ -1203,6 +1208,62 @@ struct qla_fdt_layout {
        uint8_t unused2[65];
 };
 
+/* Flash Layout Table ********************************************************/
+
+struct qla_flt_location {
+       uint8_t sig[4];
+       uint32_t start_lo;
+       uint32_t start_hi;
+       uint16_t unused;
+       uint16_t checksum;
+};
+
+struct qla_flt_header {
+       uint16_t version;
+       uint16_t length;
+       uint16_t checksum;
+       uint16_t unused;
+};
+
+#define FLT_REG_FW             0x01
+#define FLT_REG_BOOT_CODE      0x07
+#define FLT_REG_VPD_0          0x14
+#define FLT_REG_NVRAM_0                0x15
+#define FLT_REG_VPD_1          0x16
+#define FLT_REG_NVRAM_1                0x17
+#define FLT_REG_FDT            0x1a
+#define FLT_REG_FLT            0x1c
+#define FLT_REG_HW_EVENT_0     0x1d
+#define FLT_REG_HW_EVENT_1     0x1f
+#define FLT_REG_NPIV_CONF_0    0x29
+#define FLT_REG_NPIV_CONF_1    0x2a
+
+struct qla_flt_region {
+       uint32_t code;
+       uint32_t size;
+       uint32_t start;
+       uint32_t end;
+};
+
+/* Flash NPIV Configuration Table ********************************************/
+
+struct qla_npiv_header {
+       uint8_t sig[2];
+       uint16_t version;
+       uint16_t entries;
+       uint16_t unused[4];
+       uint16_t checksum;
+};
+
+struct qla_npiv_entry {
+       uint16_t flags;
+       uint16_t vf_id;
+       uint16_t qos;
+       uint16_t unused1;
+       uint8_t port_name[WWN_SIZE];
+       uint8_t node_name[WWN_SIZE];
+};
+
 /* 84XX Support **************************************************************/
 
 #define MBA_ISP84XX_ALERT      0x800f  /* Alert Notification. */
index 0b156735e9a65ee8356b520004d3302b034d261e..753dbe6cce6e5ad2289c1f34ec30de752696dbdc 100644 (file)
@@ -313,9 +313,11 @@ extern int qla24xx_get_flash_version(scsi_qla_host_t *, void *);
 extern int qla2xxx_hw_event_log(scsi_qla_host_t *, uint16_t , uint16_t,
     uint16_t, uint16_t);
 
-extern void qla2xxx_get_flash_info(scsi_qla_host_t *);
+extern int qla2xxx_get_flash_info(scsi_qla_host_t *);
 extern int qla2xxx_get_vpd_field(scsi_qla_host_t *, char *, char *, size_t);
 
+extern void qla2xxx_flash_npiv_conf(scsi_qla_host_t *);
+
 /*
  * Global Function Prototypes in qla_dbg.c source file.
  */
index ee89ddd64aae17d7098c3aae9614593f7e2c6e03..a470f2d3270d205ad35ee26519a25e9d37f90252 100644 (file)
@@ -83,6 +83,13 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha)
 
        ha->isp_ops->reset_chip(ha);
 
+       rval = qla2xxx_get_flash_info(ha);
+       if (rval) {
+               DEBUG2(printk("scsi(%ld): Unable to validate FLASH data.\n",
+                   ha->host_no));
+               return (rval);
+       }
+
        ha->isp_ops->get_flash_version(ha, ha->request_ring);
 
        qla_printk(KERN_INFO, ha, "Configure NVRAM parameters...\n");
@@ -109,7 +116,6 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha)
                rval = qla2x00_setup_chip(ha);
                if (rval)
                        return (rval);
-               qla2xxx_get_flash_info(ha);
        }
        if (IS_QLA84XX(ha)) {
                ha->cs84xx = qla84xx_get_chip(ha);
@@ -2016,7 +2022,7 @@ qla2x00_configure_loop(scsi_qla_host_t *ha)
                DEBUG3(printk("%s: exiting normally\n", __func__));
        }
 
-       /* Restore state if a resync event occured during processing */
+       /* Restore state if a resync event occurred during processing */
        if (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) {
                if (test_bit(LOCAL_LOOP_UPDATE, &save_flags))
                        set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
@@ -2561,7 +2567,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
        rval = QLA_SUCCESS;
 
        /* Try GID_PT to get device list, else GAN. */
-       swl = kcalloc(MAX_FIBRE_DEVICES, sizeof(sw_info_t), GFP_ATOMIC);
+       swl = kcalloc(MAX_FIBRE_DEVICES, sizeof(sw_info_t), GFP_KERNEL);
        if (!swl) {
                /*EMPTY*/
                DEBUG2(printk("scsi(%ld): GID_PT allocations failed, fallback "
@@ -3751,7 +3757,7 @@ qla24xx_load_risc_flash(scsi_qla_host_t *ha, uint32_t *srisc_addr)
        rval = QLA_SUCCESS;
 
        segments = FA_RISC_CODE_SEGMENTS;
-       faddr = FA_RISC_CODE_ADDR;
+       faddr = ha->flt_region_fw;
        dcode = (uint32_t *)ha->request_ring;
        *srisc_addr = 0;
 
index 92fafbdbbaabd82634377c607415c2b94cc705bf..e90afad120ee359cbc665d85c35662eeb8b0338b 100644 (file)
@@ -52,7 +52,7 @@ to_qla_parent(scsi_qla_host_t *ha)
  * @ha: HA context
  * @ha_locked: is function called with the hardware lock
  *
- * Returns non-zero if a failure occured, else zero.
+ * Returns non-zero if a failure occurred, else zero.
  */
 static inline int
 qla2x00_issue_marker(scsi_qla_host_t *ha, int ha_locked)
index d57669aa4615d33d80fe87cfe1f9550555466518..85bc0a48598b846adf7a9bb6406a60e6a17d6bb5 100644 (file)
@@ -21,17 +21,22 @@ static void qla2x00_isp_cmd(scsi_qla_host_t *ha);
  * Returns the proper CF_* direction based on CDB.
  */
 static inline uint16_t
-qla2x00_get_cmd_direction(struct scsi_cmnd *cmd)
+qla2x00_get_cmd_direction(srb_t *sp)
 {
        uint16_t cflags;
 
        cflags = 0;
 
        /* Set transfer direction */
-       if (cmd->sc_data_direction == DMA_TO_DEVICE)
+       if (sp->cmd->sc_data_direction == DMA_TO_DEVICE) {
                cflags = CF_WRITE;
-       else if (cmd->sc_data_direction == DMA_FROM_DEVICE)
+               sp->fcport->ha->qla_stats.output_bytes +=
+                   scsi_bufflen(sp->cmd);
+       } else if (sp->cmd->sc_data_direction == DMA_FROM_DEVICE) {
                cflags = CF_READ;
+               sp->fcport->ha->qla_stats.input_bytes +=
+                   scsi_bufflen(sp->cmd);
+       }
        return (cflags);
 }
 
@@ -169,7 +174,7 @@ void qla2x00_build_scsi_iocbs_32(srb_t *sp, cmd_entry_t *cmd_pkt,
 
        ha = sp->ha;
 
-       cmd_pkt->control_flags |= cpu_to_le16(qla2x00_get_cmd_direction(cmd));
+       cmd_pkt->control_flags |= cpu_to_le16(qla2x00_get_cmd_direction(sp));
 
        /* Three DSDs are available in the Command Type 2 IOCB */
        avail_dsds = 3;
@@ -228,7 +233,7 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt,
 
        ha = sp->ha;
 
-       cmd_pkt->control_flags |= cpu_to_le16(qla2x00_get_cmd_direction(cmd));
+       cmd_pkt->control_flags |= cpu_to_le16(qla2x00_get_cmd_direction(sp));
 
        /* Two DSDs are available in the Command Type 3 IOCB */
        avail_dsds = 2;
@@ -262,7 +267,7 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt,
  * qla2x00_start_scsi() - Send a SCSI command to the ISP
  * @sp: command to send to the ISP
  *
- * Returns non-zero if a failure occured, else zero.
+ * Returns non-zero if a failure occurred, else zero.
  */
 int
 qla2x00_start_scsi(srb_t *sp)
@@ -407,7 +412,7 @@ queuing_error:
  *
  * Can be called from both normal and interrupt context.
  *
- * Returns non-zero if a failure occured, else zero.
+ * Returns non-zero if a failure occurred, else zero.
  */
 int
 __qla2x00_marker(scsi_qla_host_t *ha, uint16_t loop_id, uint16_t lun,
@@ -625,12 +630,17 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt,
        ha = sp->ha;
 
        /* Set transfer direction */
-       if (cmd->sc_data_direction == DMA_TO_DEVICE)
+       if (cmd->sc_data_direction == DMA_TO_DEVICE) {
                cmd_pkt->task_mgmt_flags =
                    __constant_cpu_to_le16(TMF_WRITE_DATA);
-       else if (cmd->sc_data_direction == DMA_FROM_DEVICE)
+               sp->fcport->ha->qla_stats.output_bytes +=
+                   scsi_bufflen(sp->cmd);
+       } else if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
                cmd_pkt->task_mgmt_flags =
                    __constant_cpu_to_le16(TMF_READ_DATA);
+               sp->fcport->ha->qla_stats.input_bytes +=
+                   scsi_bufflen(sp->cmd);
+       }
 
        /* One DSD is available in the Command Type 3 IOCB */
        avail_dsds = 1;
@@ -666,7 +676,7 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt,
  * qla24xx_start_scsi() - Send a SCSI command to the ISP
  * @sp: command to send to the ISP
  *
- * Returns non-zero if a failure occured, else zero.
+ * Returns non-zero if a failure occurred, else zero.
  */
 int
 qla24xx_start_scsi(srb_t *sp)
index bf41887cdd655a4dfd0ecc04a4a8a91aa67bc265..fc4bfa7f839c8648e021f643387027d1f67cf1d2 100644 (file)
@@ -391,9 +391,9 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
                break;
 
        case MBA_LIP_OCCURRED:          /* Loop Initialization Procedure */
-               DEBUG2(printk("scsi(%ld): LIP occured (%x).\n", ha->host_no,
+               DEBUG2(printk("scsi(%ld): LIP occurred (%x).\n", ha->host_no,
                    mb[1]));
-               qla_printk(KERN_INFO, ha, "LIP occured (%x).\n", mb[1]);
+               qla_printk(KERN_INFO, ha, "LIP occurred (%x).\n", mb[1]);
 
                if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
                        atomic_set(&ha->loop_state, LOOP_DOWN);
@@ -460,7 +460,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
                DEBUG2(printk("scsi(%ld): Asynchronous LIP RESET (%x).\n",
                    ha->host_no, mb[1]));
                qla_printk(KERN_INFO, ha,
-                   "LIP reset occured (%x).\n", mb[1]);
+                   "LIP reset occurred (%x).\n", mb[1]);
 
                if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
                        atomic_set(&ha->loop_state, LOOP_DOWN);
@@ -543,7 +543,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
 
        case MBA_PORT_UPDATE:           /* Port database update */
                /*
-                * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET
+                * If PORT UPDATE is global (received LIP_OCCURRED/LIP_RESET
                 * event etc. earlier indicating loop is down) then process
                 * it.  Otherwise ignore it and Wait for RSCN to come in.
                 */
@@ -589,7 +589,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
                    "scsi(%ld): RSCN database changed -- %04x %04x %04x.\n",
                    ha->host_no, mb[1], mb[2], mb[3]));
 
-               rscn_entry = (mb[1] << 16) | mb[2];
+               rscn_entry = ((mb[1] & 0xff) << 16) | mb[2];
                host_pid = (ha->d_id.b.domain << 16) | (ha->d_id.b.area << 8) |
                    ha->d_id.b.al_pa;
                if (rscn_entry == host_pid) {
@@ -600,6 +600,8 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
                        break;
                }
 
+               /* Ignore reserved bits from RSCN-payload. */
+               rscn_entry = ((mb[1] & 0x3ff) << 16) | mb[2];
                rscn_queue_index = ha->rscn_in_ptr + 1;
                if (rscn_queue_index == MAX_RSCN_COUNT)
                        rscn_queue_index = 0;
@@ -1060,8 +1062,9 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
                resid = resid_len;
                /* Use F/W calculated residual length. */
                if (IS_FWI2_CAPABLE(ha)) {
-                       if (scsi_status & SS_RESIDUAL_UNDER &&
-                           resid != fw_resid_len) {
+                       if (!(scsi_status & SS_RESIDUAL_UNDER)) {
+                               lscsi_status = 0;
+                       } else if (resid != fw_resid_len) {
                                scsi_status &= ~SS_RESIDUAL_UNDER;
                                lscsi_status = 0;
                        }
index 813bc7784c0aa8fc6542fbce86ec7e5d8e586662..36bc6851e23dd2b13cfbbe98a6a14eac5faf0c07 100644 (file)
@@ -233,7 +233,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *pvha, mbx_cmd_t *mcp)
                        DEBUG2_3_11(printk("%s(%ld): timeout schedule "
                            "isp_abort_needed.\n", __func__, ha->host_no));
                        qla_printk(KERN_WARNING, ha,
-                           "Mailbox command timeout occured. Scheduling ISP "
+                           "Mailbox command timeout occurred. Scheduling ISP "
                            "abort.\n");
                        set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
                        qla2xxx_wake_dpc(ha);
@@ -244,7 +244,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *pvha, mbx_cmd_t *mcp)
                        DEBUG2_3_11(printk("%s(%ld): timeout calling "
                            "abort_isp\n", __func__, ha->host_no));
                        qla_printk(KERN_WARNING, ha,
-                           "Mailbox command timeout occured. Issuing ISP "
+                           "Mailbox command timeout occurred. Issuing ISP "
                            "abort.\n");
 
                        set_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags);
@@ -1995,7 +1995,7 @@ qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map)
        char *pmap;
        dma_addr_t pmap_dma;
 
-       pmap = dma_pool_alloc(ha->s_dma_pool, GFP_ATOMIC, &pmap_dma);
+       pmap = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pmap_dma);
        if (pmap  == NULL) {
                DEBUG2_3_11(printk("%s(%ld): **** Mem Alloc Failed ****",
                    __func__, ha->host_no));
index 6d0f0e5f282791fc6b8bc40c77c89a2db55b92dc..3433441b956a0e617eba3221bfa41b6479ea7e1a 100644 (file)
@@ -1517,6 +1517,7 @@ qla2xxx_scan_start(struct Scsi_Host *shost)
        set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
        set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
        set_bit(RSCN_UPDATE, &ha->dpc_flags);
+       set_bit(NPIV_CONFIG_NEEDED, &ha->dpc_flags);
 }
 
 static int
@@ -1663,8 +1664,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
                ha->gid_list_info_size = 8;
                ha->optrom_size = OPTROM_SIZE_25XX;
                ha->isp_ops = &qla25xx_isp_ops;
-               ha->hw_event_start = PCI_FUNC(pdev->devfn) ?
-                   FA_HW_EVENT1_ADDR: FA_HW_EVENT0_ADDR;
        }
        host->can_queue = ha->request_q_length + 128;
 
@@ -2433,6 +2432,12 @@ qla2x00_do_dpc(void *data)
                            ha->host_no));
                }
 
+               if (test_bit(NPIV_CONFIG_NEEDED, &ha->dpc_flags) &&
+                   atomic_read(&ha->loop_state) == LOOP_READY) {
+                       clear_bit(NPIV_CONFIG_NEEDED, &ha->dpc_flags);
+                       qla2xxx_flash_npiv_conf(ha);
+               }
+
                if (!ha->interrupts_on)
                        ha->isp_ops->enable_intrs(ha);
 
index 1bca744749353d24e7d1651efde761a4f473c93f..90a13211717f7d367a89c3b7f0b74fc5dd0f113c 100644 (file)
@@ -543,23 +543,198 @@ qla24xx_get_flash_manufacturer(scsi_qla_host_t *ha, uint8_t *man_id,
        }
 }
 
-void
-qla2xxx_get_flash_info(scsi_qla_host_t *ha)
+static int
+qla2xxx_find_flt_start(scsi_qla_host_t *ha, uint32_t *start)
+{
+       const char *loc, *locations[] = { "DEF", "PCI" };
+       uint32_t pcihdr, pcids;
+       uint32_t *dcode;
+       uint8_t *buf, *bcode, last_image;
+       uint16_t cnt, chksum, *wptr;
+       struct qla_flt_location *fltl;
+
+       /*
+        * FLT-location structure resides after the last PCI region.
+        */
+
+       /* Begin with sane defaults. */
+       loc = locations[0];
+       *start = IS_QLA24XX_TYPE(ha) ? FA_FLASH_LAYOUT_ADDR_24:
+           FA_FLASH_LAYOUT_ADDR;
+
+       /* Begin with first PCI expansion ROM header. */
+       buf = (uint8_t *)ha->request_ring;
+       dcode = (uint32_t *)ha->request_ring;
+       pcihdr = 0;
+       last_image = 1;
+       do {
+               /* Verify PCI expansion ROM header. */
+               qla24xx_read_flash_data(ha, dcode, pcihdr >> 2, 0x20);
+               bcode = buf + (pcihdr % 4);
+               if (bcode[0x0] != 0x55 || bcode[0x1] != 0xaa)
+                       goto end;
+
+               /* Locate PCI data structure. */
+               pcids = pcihdr + ((bcode[0x19] << 8) | bcode[0x18]);
+               qla24xx_read_flash_data(ha, dcode, pcids >> 2, 0x20);
+               bcode = buf + (pcihdr % 4);
+
+               /* Validate signature of PCI data structure. */
+               if (bcode[0x0] != 'P' || bcode[0x1] != 'C' ||
+                   bcode[0x2] != 'I' || bcode[0x3] != 'R')
+                       goto end;
+
+               last_image = bcode[0x15] & BIT_7;
+
+               /* Locate next PCI expansion ROM. */
+               pcihdr += ((bcode[0x11] << 8) | bcode[0x10]) * 512;
+       } while (!last_image);
+
+       /* Now verify FLT-location structure. */
+       fltl = (struct qla_flt_location *)ha->request_ring;
+       qla24xx_read_flash_data(ha, dcode, pcihdr >> 2,
+           sizeof(struct qla_flt_location) >> 2);
+       if (fltl->sig[0] != 'Q' || fltl->sig[1] != 'F' ||
+           fltl->sig[2] != 'L' || fltl->sig[3] != 'T')
+               goto end;
+
+       wptr = (uint16_t *)ha->request_ring;
+       cnt = sizeof(struct qla_flt_location) >> 1;
+       for (chksum = 0; cnt; cnt--)
+               chksum += le16_to_cpu(*wptr++);
+       if (chksum) {
+               qla_printk(KERN_ERR, ha,
+                   "Inconsistent FLTL detected: checksum=0x%x.\n", chksum);
+               qla2x00_dump_buffer(buf, sizeof(struct qla_flt_location));
+               return QLA_FUNCTION_FAILED;
+       }
+
+       /* Good data.  Use specified location. */
+       loc = locations[1];
+       *start = le16_to_cpu(fltl->start_hi) << 16 |
+           le16_to_cpu(fltl->start_lo);
+end:
+       DEBUG2(qla_printk(KERN_DEBUG, ha, "FLTL[%s] = 0x%x.\n", loc, *start));
+       return QLA_SUCCESS;
+}
+
+static void
+qla2xxx_get_flt_info(scsi_qla_host_t *ha, uint32_t flt_addr)
+{
+       const char *loc, *locations[] = { "DEF", "FLT" };
+       uint16_t *wptr;
+       uint16_t cnt, chksum;
+       uint32_t start;
+       struct qla_flt_header *flt;
+       struct qla_flt_region *region;
+
+       ha->flt_region_flt = flt_addr;
+       wptr = (uint16_t *)ha->request_ring;
+       flt = (struct qla_flt_header *)ha->request_ring;
+       region = (struct qla_flt_region *)&flt[1];
+       ha->isp_ops->read_optrom(ha, (uint8_t *)ha->request_ring,
+           flt_addr << 2, OPTROM_BURST_SIZE);
+       if (*wptr == __constant_cpu_to_le16(0xffff))
+               goto no_flash_data;
+       if (flt->version != __constant_cpu_to_le16(1)) {
+               DEBUG2(qla_printk(KERN_INFO, ha, "Unsupported FLT detected: "
+                   "version=0x%x length=0x%x checksum=0x%x.\n",
+                   le16_to_cpu(flt->version), le16_to_cpu(flt->length),
+                   le16_to_cpu(flt->checksum)));
+               goto no_flash_data;
+       }
+
+       cnt = (sizeof(struct qla_flt_header) + le16_to_cpu(flt->length)) >> 1;
+       for (chksum = 0; cnt; cnt--)
+               chksum += le16_to_cpu(*wptr++);
+       if (chksum) {
+               DEBUG2(qla_printk(KERN_INFO, ha, "Inconsistent FLT detected: "
+                   "version=0x%x length=0x%x checksum=0x%x.\n",
+                   le16_to_cpu(flt->version), le16_to_cpu(flt->length),
+                   chksum));
+               goto no_flash_data;
+       }
+
+       loc = locations[1];
+       cnt = le16_to_cpu(flt->length) / sizeof(struct qla_flt_region);
+       for ( ; cnt; cnt--, region++) {
+               /* Store addresses as DWORD offsets. */
+               start = le32_to_cpu(region->start) >> 2;
+
+               DEBUG3(qla_printk(KERN_DEBUG, ha, "FLT[%02x]: start=0x%x "
+                   "end=0x%x size=0x%x.\n", le32_to_cpu(region->code), start,
+                   le32_to_cpu(region->end) >> 2, le32_to_cpu(region->size)));
+
+               switch (le32_to_cpu(region->code)) {
+               case FLT_REG_FW:
+                       ha->flt_region_fw = start;
+                       break;
+               case FLT_REG_BOOT_CODE:
+                       ha->flt_region_boot = start;
+                       break;
+               case FLT_REG_VPD_0:
+                       ha->flt_region_vpd_nvram = start;
+                       break;
+               case FLT_REG_FDT:
+                       ha->flt_region_fdt = start;
+                       break;
+               case FLT_REG_HW_EVENT_0:
+                       if (!PCI_FUNC(ha->pdev->devfn))
+                               ha->flt_region_hw_event = start;
+                       break;
+               case FLT_REG_HW_EVENT_1:
+                       if (PCI_FUNC(ha->pdev->devfn))
+                               ha->flt_region_hw_event = start;
+                       break;
+               case FLT_REG_NPIV_CONF_0:
+                       if (!PCI_FUNC(ha->pdev->devfn))
+                               ha->flt_region_npiv_conf = start;
+                       break;
+               case FLT_REG_NPIV_CONF_1:
+                       if (PCI_FUNC(ha->pdev->devfn))
+                               ha->flt_region_npiv_conf = start;
+                       break;
+               }
+       }
+       goto done;
+
+no_flash_data:
+       /* Use hardcoded defaults. */
+       loc = locations[0];
+       ha->flt_region_fw = FA_RISC_CODE_ADDR;
+       ha->flt_region_boot = FA_BOOT_CODE_ADDR;
+       ha->flt_region_vpd_nvram = FA_VPD_NVRAM_ADDR;
+       ha->flt_region_fdt = IS_QLA24XX_TYPE(ha) ? FA_FLASH_DESCR_ADDR_24:
+           FA_FLASH_DESCR_ADDR;
+       ha->flt_region_hw_event = !PCI_FUNC(ha->pdev->devfn) ?
+           FA_HW_EVENT0_ADDR: FA_HW_EVENT1_ADDR;
+       ha->flt_region_npiv_conf = !PCI_FUNC(ha->pdev->devfn) ?
+           (IS_QLA24XX_TYPE(ha) ? FA_NPIV_CONF0_ADDR_24: FA_NPIV_CONF0_ADDR):
+           (IS_QLA24XX_TYPE(ha) ? FA_NPIV_CONF1_ADDR_24: FA_NPIV_CONF1_ADDR);
+done:
+       DEBUG2(qla_printk(KERN_DEBUG, ha, "FLT[%s]: boot=0x%x fw=0x%x "
+           "vpd_nvram=0x%x fdt=0x%x flt=0x%x hwe=0x%x npiv=0x%x.\n", loc,
+           ha->flt_region_boot, ha->flt_region_fw, ha->flt_region_vpd_nvram,
+           ha->flt_region_fdt, ha->flt_region_flt, ha->flt_region_hw_event,
+           ha->flt_region_npiv_conf));
+}
+
+static void
+qla2xxx_get_fdt_info(scsi_qla_host_t *ha)
 {
 #define FLASH_BLK_SIZE_32K     0x8000
 #define FLASH_BLK_SIZE_64K     0x10000
+       const char *loc, *locations[] = { "MID", "FDT" };
        uint16_t cnt, chksum;
        uint16_t *wptr;
        struct qla_fdt_layout *fdt;
        uint8_t man_id, flash_id;
-
-       if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
-               return;
+       uint16_t mid, fid;
 
        wptr = (uint16_t *)ha->request_ring;
        fdt = (struct qla_fdt_layout *)ha->request_ring;
        ha->isp_ops->read_optrom(ha, (uint8_t *)ha->request_ring,
-           FA_FLASH_DESCR_ADDR << 2, OPTROM_BURST_SIZE);
+           ha->flt_region_fdt << 2, OPTROM_BURST_SIZE);
        if (*wptr == __constant_cpu_to_le16(0xffff))
                goto no_flash_data;
        if (fdt->sig[0] != 'Q' || fdt->sig[1] != 'L' || fdt->sig[2] != 'I' ||
@@ -577,7 +752,10 @@ qla2xxx_get_flash_info(scsi_qla_host_t *ha)
                goto no_flash_data;
        }
 
-       ha->fdt_odd_index = le16_to_cpu(fdt->man_id) == 0x1f;
+       loc = locations[1];
+       mid = le16_to_cpu(fdt->man_id);
+       fid = le16_to_cpu(fdt->id);
+       ha->fdt_odd_index = mid == 0x1f;
        ha->fdt_wrt_disable = fdt->wrt_disable_bits;
        ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0300 | fdt->erase_cmd);
        ha->fdt_block_size = le32_to_cpu(fdt->block_size);
@@ -588,16 +766,12 @@ qla2xxx_get_flash_info(scsi_qla_host_t *ha)
                    flash_conf_to_access_addr(0x0300 | fdt->protect_sec_cmd):
                    flash_conf_to_access_addr(0x0336);
        }
-
-       DEBUG2(qla_printk(KERN_DEBUG, ha, "Flash[FDT]: (0x%x/0x%x) erase=0x%x "
-           "pro=%x upro=%x idx=%d wrtd=0x%x blk=0x%x.\n",
-           le16_to_cpu(fdt->man_id), le16_to_cpu(fdt->id), ha->fdt_erase_cmd,
-           ha->fdt_protect_sec_cmd, ha->fdt_unprotect_sec_cmd,
-           ha->fdt_odd_index, ha->fdt_wrt_disable, ha->fdt_block_size));
-       return;
-
+       goto done;
 no_flash_data:
+       loc = locations[0];
        qla24xx_get_flash_manufacturer(ha, &man_id, &flash_id);
+       mid = man_id;
+       fid = flash_id;
        ha->fdt_wrt_disable = 0x9c;
        ha->fdt_erase_cmd = flash_conf_to_access_addr(0x03d8);
        switch (man_id) {
@@ -625,14 +799,117 @@ no_flash_data:
                ha->fdt_block_size = FLASH_BLK_SIZE_64K;
                break;
        }
-
-       DEBUG2(qla_printk(KERN_DEBUG, ha, "Flash[MID]: (0x%x/0x%x) erase=0x%x "
-           "pro=%x upro=%x idx=%d wrtd=0x%x blk=0x%x.\n", man_id, flash_id,
+done:
+       DEBUG2(qla_printk(KERN_DEBUG, ha, "FDT[%s]: (0x%x/0x%x) erase=0x%x "
+           "pro=%x upro=%x idx=%d wrtd=0x%x blk=0x%x.\n", loc, mid, fid,
            ha->fdt_erase_cmd, ha->fdt_protect_sec_cmd,
            ha->fdt_unprotect_sec_cmd, ha->fdt_odd_index, ha->fdt_wrt_disable,
            ha->fdt_block_size));
 }
 
+int
+qla2xxx_get_flash_info(scsi_qla_host_t *ha)
+{
+       int ret;
+       uint32_t flt_addr;
+
+       if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
+               return QLA_SUCCESS;
+
+       ret = qla2xxx_find_flt_start(ha, &flt_addr);
+       if (ret != QLA_SUCCESS)
+               return ret;
+
+       qla2xxx_get_flt_info(ha, flt_addr);
+       qla2xxx_get_fdt_info(ha);
+
+       return QLA_SUCCESS;
+}
+
+void
+qla2xxx_flash_npiv_conf(scsi_qla_host_t *ha)
+{
+#define NPIV_CONFIG_SIZE       (16*1024)
+       void *data;
+       uint16_t *wptr;
+       uint16_t cnt, chksum;
+       struct qla_npiv_header hdr;
+       struct qla_npiv_entry *entry;
+
+       if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
+               return;
+
+       ha->isp_ops->read_optrom(ha, (uint8_t *)&hdr,
+           ha->flt_region_npiv_conf << 2, sizeof(struct qla_npiv_header));
+       if (hdr.version == __constant_cpu_to_le16(0xffff))
+               return;
+       if (hdr.version != __constant_cpu_to_le16(1)) {
+               DEBUG2(qla_printk(KERN_INFO, ha, "Unsupported NPIV-Config "
+                   "detected: version=0x%x entries=0x%x checksum=0x%x.\n",
+                   le16_to_cpu(hdr.version), le16_to_cpu(hdr.entries),
+                   le16_to_cpu(hdr.checksum)));
+               return;
+       }
+
+       data = kmalloc(NPIV_CONFIG_SIZE, GFP_KERNEL);
+       if (!data) {
+               DEBUG2(qla_printk(KERN_INFO, ha, "NPIV-Config: Unable to "
+                   "allocate memory.\n"));
+               return;
+       }
+
+       ha->isp_ops->read_optrom(ha, (uint8_t *)data,
+           ha->flt_region_npiv_conf << 2, NPIV_CONFIG_SIZE);
+
+       cnt = (sizeof(struct qla_npiv_header) + le16_to_cpu(hdr.entries) *
+           sizeof(struct qla_npiv_entry)) >> 1;
+       for (wptr = data, chksum = 0; cnt; cnt--)
+               chksum += le16_to_cpu(*wptr++);
+       if (chksum) {
+               DEBUG2(qla_printk(KERN_INFO, ha, "Inconsistent NPIV-Config "
+                   "detected: version=0x%x entries=0x%x checksum=0x%x.\n",
+                   le16_to_cpu(hdr.version), le16_to_cpu(hdr.entries),
+                   chksum));
+               goto done;
+       }
+
+       entry = data + sizeof(struct qla_npiv_header);
+       cnt = le16_to_cpu(hdr.entries);
+       for ( ; cnt; cnt--, entry++) {
+               uint16_t flags;
+               struct fc_vport_identifiers vid;
+               struct fc_vport *vport;
+
+               flags = le16_to_cpu(entry->flags);
+               if (flags == 0xffff)
+                       continue;
+               if ((flags & BIT_0) == 0)
+                       continue;
+
+               memset(&vid, 0, sizeof(vid));
+               vid.roles = FC_PORT_ROLE_FCP_INITIATOR;
+               vid.vport_type = FC_PORTTYPE_NPIV;
+               vid.disable = false;
+               vid.port_name = wwn_to_u64(entry->port_name);
+               vid.node_name = wwn_to_u64(entry->node_name);
+
+               DEBUG2(qla_printk(KERN_DEBUG, ha, "NPIV[%02x]: wwpn=%llx "
+                   "wwnn=%llx vf_id=0x%x qos=0x%x.\n", cnt,
+                   (unsigned long long)vid.port_name,
+                   (unsigned long long)vid.node_name,
+                   le16_to_cpu(entry->vf_id), le16_to_cpu(entry->qos)));
+
+               vport = fc_vport_create(ha->host, 0, &vid);
+               if (!vport)
+                       qla_printk(KERN_INFO, ha, "NPIV-Config: Failed to "
+                           "create vport [%02x]: wwpn=%llx wwnn=%llx.\n", cnt,
+                           (unsigned long long)vid.port_name,
+                           (unsigned long long)vid.node_name);
+       }
+done:
+       kfree(data);
+}
+
 static void
 qla24xx_unprotect_flash(scsi_qla_host_t *ha)
 {
@@ -920,7 +1197,8 @@ qla25xx_read_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
        dwptr = (uint32_t *)buf;
        for (i = 0; i < bytes >> 2; i++, naddr++)
                dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha,
-                   flash_data_to_access_addr(FA_VPD_NVRAM_ADDR | naddr)));
+                   flash_data_to_access_addr(ha->flt_region_vpd_nvram |
+                   naddr)));
 
        return buf;
 }
@@ -935,10 +1213,10 @@ qla25xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
        dbuf = vmalloc(RMW_BUFFER_SIZE);
        if (!dbuf)
                return QLA_MEMORY_ALLOC_FAILED;
-       ha->isp_ops->read_optrom(ha, dbuf, FA_VPD_NVRAM_ADDR << 2,
+       ha->isp_ops->read_optrom(ha, dbuf, ha->flt_region_vpd_nvram << 2,
            RMW_BUFFER_SIZE);
        memcpy(dbuf + (naddr << 2), buf, bytes);
-       ha->isp_ops->write_optrom(ha, dbuf, FA_VPD_NVRAM_ADDR << 2,
+       ha->isp_ops->write_optrom(ha, dbuf, ha->flt_region_vpd_nvram << 2,
            RMW_BUFFER_SIZE);
        vfree(dbuf);
 
@@ -2166,7 +2444,7 @@ qla2x00_get_flash_version(scsi_qla_host_t *ha, void *mbuf)
                memset(dbyte, 0, 8);
                dcode = (uint16_t *)dbyte;
 
-               qla2x00_read_flash_data(ha, dbyte, FA_RISC_CODE_ADDR * 4 + 10,
+               qla2x00_read_flash_data(ha, dbyte, ha->flt_region_fw * 4 + 10,
                    8);
                DEBUG3(printk("%s(%ld): dumping fw ver from flash:\n",
                    __func__, ha->host_no));
@@ -2177,7 +2455,7 @@ qla2x00_get_flash_version(scsi_qla_host_t *ha, void *mbuf)
                    (dcode[0] == 0 && dcode[1] == 0 && dcode[2] == 0 &&
                    dcode[3] == 0)) {
                        DEBUG2(printk("%s(): Unrecognized fw revision at "
-                           "%x.\n", __func__, FA_RISC_CODE_ADDR * 4));
+                           "%x.\n", __func__, ha->flt_region_fw * 4));
                } else {
                        /* values are in big endian */
                        ha->fw_revision[0] = dbyte[0] << 16 | dbyte[1];
@@ -2212,7 +2490,7 @@ qla24xx_get_flash_version(scsi_qla_host_t *ha, void *mbuf)
        dcode = mbuf;
 
        /* Begin with first PCI expansion ROM header. */
-       pcihdr = 0;
+       pcihdr = ha->flt_region_boot;
        last_image = 1;
        do {
                /* Verify PCI expansion ROM header. */
@@ -2282,7 +2560,7 @@ qla24xx_get_flash_version(scsi_qla_host_t *ha, void *mbuf)
        memset(ha->fw_revision, 0, sizeof(ha->fw_revision));
        dcode = mbuf;
 
-       qla24xx_read_flash_data(ha, dcode, FA_RISC_CODE_ADDR + 4, 4);
+       qla24xx_read_flash_data(ha, dcode, ha->flt_region_fw + 4, 4);
        for (i = 0; i < 4; i++)
                dcode[i] = be32_to_cpu(dcode[i]);
 
@@ -2291,7 +2569,7 @@ qla24xx_get_flash_version(scsi_qla_host_t *ha, void *mbuf)
            (dcode[0] == 0 && dcode[1] == 0 && dcode[2] == 0 &&
            dcode[3] == 0)) {
                DEBUG2(printk("%s(): Unrecognized fw version at %x.\n",
-                   __func__, FA_RISC_CODE_ADDR));
+                   __func__, ha->flt_region_fw));
        } else {
                ha->fw_revision[0] = dcode[0];
                ha->fw_revision[1] = dcode[1];
@@ -2355,7 +2633,7 @@ qla2xxx_hw_event_store(scsi_qla_host_t *ha, uint32_t *fdata)
        /* Locate first empty entry. */
        for (;;) {
                if (ha->hw_event_ptr >=
-                   ha->hw_event_start + FA_HW_EVENT_SIZE) {
+                   ha->flt_region_hw_event + FA_HW_EVENT_SIZE) {
                        DEBUG2(qla_printk(KERN_WARNING, ha,
                            "HW event -- Log Full!\n"));
                        return QLA_MEMORY_ALLOC_FAILED;
@@ -2391,7 +2669,7 @@ qla2xxx_hw_event_log(scsi_qla_host_t *ha, uint16_t code, uint16_t d1,
        int rval;
        uint32_t marker[2], fdata[4];
 
-       if (ha->hw_event_start == 0)
+       if (ha->flt_region_hw_event == 0)
                return QLA_FUNCTION_FAILED;
 
        DEBUG2(qla_printk(KERN_WARNING, ha,
@@ -2406,7 +2684,7 @@ qla2xxx_hw_event_log(scsi_qla_host_t *ha, uint16_t code, uint16_t d1,
                    QLA_DRIVER_PATCH_VER, QLA_DRIVER_BETA_VER);
 
                /* Locate marker. */
-               ha->hw_event_ptr = ha->hw_event_start;
+               ha->hw_event_ptr = ha->flt_region_hw_event;
                for (;;) {
                        qla24xx_read_flash_data(ha, fdata, ha->hw_event_ptr,
                            4);
@@ -2415,7 +2693,7 @@ qla2xxx_hw_event_log(scsi_qla_host_t *ha, uint16_t code, uint16_t d1,
                                break;
                        ha->hw_event_ptr += FA_HW_EVENT_ENTRY_SIZE;
                        if (ha->hw_event_ptr >=
-                           ha->hw_event_start + FA_HW_EVENT_SIZE) {
+                           ha->flt_region_hw_event + FA_HW_EVENT_SIZE) {
                                DEBUG2(qla_printk(KERN_WARNING, ha,
                                    "HW event -- Log Full!\n"));
                                return QLA_MEMORY_ALLOC_FAILED;
index 4160e4caa7b97af229f03b74bb472fb7a4dd53b3..be5e299df528e22eed62f8ac25d03c01a11630d7 100644 (file)
@@ -7,7 +7,7 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION      "8.02.01-k7"
+#define QLA2XXX_VERSION      "8.02.01-k8"
 
 #define QLA_DRIVER_MAJOR_VER   8
 #define QLA_DRIVER_MINOR_VER   2
index 88bebb13bc520ab0d3959426adcaf3f30986a320..de8279ad7d89dca83cc1e32e2f8fc5d091d7b3fb 100644 (file)
@@ -1542,7 +1542,7 @@ static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd)
        DEBUG2(printk(KERN_INFO
                      "scsi%ld: DEVICE_RESET cmd=%p jiffies = 0x%lx, to=%x,"
                      "dpc_flags=%lx, status=%x allowed=%d\n", ha->host_no,
-                     cmd, jiffies, cmd->timeout_per_command / HZ,
+                     cmd, jiffies, cmd->request->timeout / HZ,
                      ha->dpc_flags, cmd->result, cmd->allowed));
 
        /* FIXME: wait for hba to go online */
@@ -1598,7 +1598,7 @@ static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd)
        DEBUG2(printk(KERN_INFO
                      "scsi%ld: TARGET_DEVICE_RESET cmd=%p jiffies = 0x%lx, "
                      "to=%x,dpc_flags=%lx, status=%x allowed=%d\n",
-                     ha->host_no, cmd, jiffies, cmd->timeout_per_command / HZ,
+                     ha->host_no, cmd, jiffies, cmd->request->timeout / HZ,
                      ha->dpc_flags, cmd->result, cmd->allowed));
 
        stat = qla4xxx_reset_target(ha, ddb_entry);
index ee6be596503d1515dc855e6e5715267ac4edb4e1..2ac3cb2b9081836e53ce3d8c2f5567d9e4563831 100644 (file)
@@ -291,7 +291,6 @@ struct scsi_cmnd *scsi_get_command(struct scsi_device *dev, gfp_t gfp_mask)
                unsigned long flags;
 
                cmd->device = dev;
-               init_timer(&cmd->eh_timeout);
                INIT_LIST_HEAD(&cmd->list);
                spin_lock_irqsave(&dev->list_lock, flags);
                list_add_tail(&cmd->list, &dev->cmd_list);
@@ -652,26 +651,33 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
        unsigned long timeout;
        int rtn = 0;
 
+       /*
+        * We will use a queued command if possible, otherwise we will
+        * emulate the queuing and calling of completion function ourselves.
+        */
+       atomic_inc(&cmd->device->iorequest_cnt);
+
        /* check if the device is still usable */
        if (unlikely(cmd->device->sdev_state == SDEV_DEL)) {
                /* in SDEV_DEL we error all commands. DID_NO_CONNECT
                 * returns an immediate error upwards, and signals
                 * that the device is no longer present */
                cmd->result = DID_NO_CONNECT << 16;
-               atomic_inc(&cmd->device->iorequest_cnt);
-               __scsi_done(cmd);
+               scsi_done(cmd);
                /* return 0 (because the command has been processed) */
                goto out;
        }
 
-       /* Check to see if the scsi lld put this device into state SDEV_BLOCK. */
-       if (unlikely(cmd->device->sdev_state == SDEV_BLOCK)) {
+       /* Check to see if the scsi lld made this device blocked. */
+       if (unlikely(scsi_device_blocked(cmd->device))) {
                /* 
-                * in SDEV_BLOCK, the command is just put back on the device
-                * queue.  The suspend state has already blocked the queue so
-                * future requests should not occur until the device 
-                * transitions out of the suspend state.
+                * in blocked state, the command is just put back on
+                * the device queue.  The suspend state has already
+                * blocked the queue so future requests should not
+                * occur until the device transitions out of the
+                * suspend state.
                 */
+
                scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY);
 
                SCSI_LOG_MLQUEUE(3, printk("queuecommand : device blocked \n"));
@@ -714,20 +720,8 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
                host->resetting = 0;
        }
 
-       /* 
-        * AK: unlikely race here: for some reason the timer could
-        * expire before the serial number is set up below.
-        */
-       scsi_add_timer(cmd, cmd->timeout_per_command, scsi_times_out);
-
        scsi_log_send(cmd);
 
-       /*
-        * We will use a queued command if possible, otherwise we will
-        * emulate the queuing and calling of completion function ourselves.
-        */
-       atomic_inc(&cmd->device->iorequest_cnt);
-
        /*
         * Before we queue this command, check if the command
         * length exceeds what the host adapter can handle.
@@ -744,6 +738,12 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
        }
 
        spin_lock_irqsave(host->host_lock, flags);
+       /*
+        * AK: unlikely race here: for some reason the timer could
+        * expire before the serial number is set up below.
+        *
+        * TODO: kill serial or move to blk layer
+        */
        scsi_cmd_get_serial(host, cmd); 
 
        if (unlikely(host->shost_state == SHOST_DEL)) {
@@ -754,12 +754,8 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
        }
        spin_unlock_irqrestore(host->host_lock, flags);
        if (rtn) {
-               if (scsi_delete_timer(cmd)) {
-                       atomic_inc(&cmd->device->iodone_cnt);
-                       scsi_queue_insert(cmd,
-                                         (rtn == SCSI_MLQUEUE_DEVICE_BUSY) ?
-                                         rtn : SCSI_MLQUEUE_HOST_BUSY);
-               }
+               scsi_queue_insert(cmd, (rtn == SCSI_MLQUEUE_DEVICE_BUSY) ?
+                                               rtn : SCSI_MLQUEUE_HOST_BUSY);
                SCSI_LOG_MLQUEUE(3,
                    printk("queuecommand : request rejected\n"));
        }
@@ -769,24 +765,6 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
        return rtn;
 }
 
-/**
- * scsi_req_abort_cmd -- Request command recovery for the specified command
- * @cmd: pointer to the SCSI command of interest
- *
- * This function requests that SCSI Core start recovery for the
- * command by deleting the timer and adding the command to the eh
- * queue.  It can be called by either LLDDs or SCSI Core.  LLDDs who
- * implement their own error recovery MAY ignore the timeout event if
- * they generated scsi_req_abort_cmd.
- */
-void scsi_req_abort_cmd(struct scsi_cmnd *cmd)
-{
-       if (!scsi_delete_timer(cmd))
-               return;
-       scsi_times_out(cmd);
-}
-EXPORT_SYMBOL(scsi_req_abort_cmd);
-
 /**
  * scsi_done - Enqueue the finished SCSI command into the done queue.
  * @cmd: The SCSI Command for which a low-level device driver (LLDD) gives
@@ -802,42 +780,7 @@ EXPORT_SYMBOL(scsi_req_abort_cmd);
  */
 static void scsi_done(struct scsi_cmnd *cmd)
 {
-       /*
-        * We don't have to worry about this one timing out anymore.
-        * If we are unable to remove the timer, then the command
-        * has already timed out.  In which case, we have no choice but to
-        * let the timeout function run, as we have no idea where in fact
-        * that function could really be.  It might be on another processor,
-        * etc, etc.
-        */
-       if (!scsi_delete_timer(cmd))
-               return;
-       __scsi_done(cmd);
-}
-
-/* Private entry to scsi_done() to complete a command when the timer
- * isn't running --- used by scsi_times_out */
-void __scsi_done(struct scsi_cmnd *cmd)
-{
-       struct request *rq = cmd->request;
-
-       /*
-        * Set the serial numbers back to zero
-        */
-       cmd->serial_number = 0;
-
-       atomic_inc(&cmd->device->iodone_cnt);
-       if (cmd->result)
-               atomic_inc(&cmd->device->ioerr_cnt);
-
-       BUG_ON(!rq);
-
-       /*
-        * The uptodate/nbytes values don't matter, as we allow partial
-        * completes and thus will check this in the softirq callback
-        */
-       rq->completion_data = cmd;
-       blk_complete_request(rq);
+       blk_complete_request(cmd->request);
 }
 
 /* Move this to a header if it becomes more generally useful */
index 39ce3aba1dac5f459d668ee7ce4d15832918ec66..fecefa05cb62c4f586a1f1ed7183c4f93cbac902 100644 (file)
@@ -111,70 +111,9 @@ int scsi_eh_scmd_add(struct scsi_cmnd *scmd, int eh_flag)
        return ret;
 }
 
-/**
- * scsi_add_timer - Start timeout timer for a single scsi command.
- * @scmd:      scsi command that is about to start running.
- * @timeout:   amount of time to allow this command to run.
- * @complete:  timeout function to call if timer isn't canceled.
- *
- * Notes:
- *    This should be turned into an inline function.  Each scsi command
- *    has its own timer, and as it is added to the queue, we set up the
- *    timer.  When the command completes, we cancel the timer.
- */
-void scsi_add_timer(struct scsi_cmnd *scmd, int timeout,
-                   void (*complete)(struct scsi_cmnd *))
-{
-
-       /*
-        * If the clock was already running for this command, then
-        * first delete the timer.  The timer handling code gets rather
-        * confused if we don't do this.
-        */
-       if (scmd->eh_timeout.function)
-               del_timer(&scmd->eh_timeout);
-
-       scmd->eh_timeout.data = (unsigned long)scmd;
-       scmd->eh_timeout.expires = jiffies + timeout;
-       scmd->eh_timeout.function = (void (*)(unsigned long)) complete;
-
-       SCSI_LOG_ERROR_RECOVERY(5, printk("%s: scmd: %p, time:"
-                                         " %d, (%p)\n", __func__,
-                                         scmd, timeout, complete));
-
-       add_timer(&scmd->eh_timeout);
-}
-
-/**
- * scsi_delete_timer - Delete/cancel timer for a given function.
- * @scmd:      Cmd that we are canceling timer for
- *
- * Notes:
- *     This should be turned into an inline function.
- *
- * Return value:
- *     1 if we were able to detach the timer.  0 if we blew it, and the
- *     timer function has already started to run.
- */
-int scsi_delete_timer(struct scsi_cmnd *scmd)
-{
-       int rtn;
-
-       rtn = del_timer(&scmd->eh_timeout);
-
-       SCSI_LOG_ERROR_RECOVERY(5, printk("%s: scmd: %p,"
-                                        " rtn: %d\n", __func__,
-                                        scmd, rtn));
-
-       scmd->eh_timeout.data = (unsigned long)NULL;
-       scmd->eh_timeout.function = NULL;
-
-       return rtn;
-}
-
 /**
  * scsi_times_out - Timeout function for normal scsi commands.
- * @scmd:      Cmd that is timing out.
+ * @req:       request that is timing out.
  *
  * Notes:
  *     We do not need to lock this.  There is the potential for a race
@@ -182,9 +121,11 @@ int scsi_delete_timer(struct scsi_cmnd *scmd)
  *     normal completion function determines that the timer has already
  *     fired, then it mustn't do anything.
  */
-void scsi_times_out(struct scsi_cmnd *scmd)
+enum blk_eh_timer_return scsi_times_out(struct request *req)
 {
-       enum scsi_eh_timer_return (* eh_timed_out)(struct scsi_cmnd *);
+       struct scsi_cmnd *scmd = req->special;
+       enum blk_eh_timer_return (*eh_timed_out)(struct scsi_cmnd *);
+       enum blk_eh_timer_return rtn = BLK_EH_NOT_HANDLED;
 
        scsi_log_completion(scmd, TIMEOUT_ERROR);
 
@@ -196,22 +137,20 @@ void scsi_times_out(struct scsi_cmnd *scmd)
                eh_timed_out = NULL;
 
        if (eh_timed_out)
-               switch (eh_timed_out(scmd)) {
-               case EH_HANDLED:
-                       __scsi_done(scmd);
-                       return;
-               case EH_RESET_TIMER:
-                       scsi_add_timer(scmd, scmd->timeout_per_command,
-                                      scsi_times_out);
-                       return;
-               case EH_NOT_HANDLED:
+               rtn = eh_timed_out(scmd);
+               switch (rtn) {
+               case BLK_EH_NOT_HANDLED:
                        break;
+               default:
+                       return rtn;
                }
 
        if (unlikely(!scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD))) {
                scmd->result |= DID_TIME_OUT << 16;
-               __scsi_done(scmd);
+               return BLK_EH_HANDLED;
        }
+
+       return BLK_EH_NOT_HANDLED;
 }
 
 /**
@@ -1793,7 +1732,6 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
 
        blk_rq_init(NULL, &req);
        scmd->request = &req;
-       memset(&scmd->eh_timeout, 0, sizeof(scmd->eh_timeout));
 
        scmd->cmnd = req.cmd;
 
@@ -1804,8 +1742,6 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
 
        scmd->sc_data_direction         = DMA_BIDIRECTIONAL;
 
-       init_timer(&scmd->eh_timeout);
-
        spin_lock_irqsave(shost->host_lock, flags);
        shost->tmf_in_progress = 1;
        spin_unlock_irqrestore(shost->host_lock, flags);
index 62307bd794a924c1f04d6b6822aa61dd2ef875c3..98ee55ced5922c4ff14634bd320725eb2d3b5db0 100644 (file)
@@ -1181,7 +1181,6 @@ int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req)
        
        cmd->transfersize = req->data_len;
        cmd->allowed = req->retries;
-       cmd->timeout_per_command = req->timeout;
        return BLKPREP_OK;
 }
 EXPORT_SYMBOL(scsi_setup_blk_pc_cmnd);
@@ -1251,6 +1250,7 @@ int scsi_prep_state_check(struct scsi_device *sdev, struct request *req)
                        break;
                case SDEV_QUIESCE:
                case SDEV_BLOCK:
+               case SDEV_CREATED_BLOCK:
                        /*
                         * If the devices is blocked we defer normal commands.
                         */
@@ -1416,17 +1416,26 @@ static void scsi_kill_request(struct request *req, struct request_queue *q)
        spin_unlock(shost->host_lock);
        spin_lock(sdev->request_queue->queue_lock);
 
-       __scsi_done(cmd);
+       blk_complete_request(req);
 }
 
 static void scsi_softirq_done(struct request *rq)
 {
-       struct scsi_cmnd *cmd = rq->completion_data;
-       unsigned long wait_for = (cmd->allowed + 1) * cmd->timeout_per_command;
+       struct scsi_cmnd *cmd = rq->special;
+       unsigned long wait_for = (cmd->allowed + 1) * rq->timeout;
        int disposition;
 
        INIT_LIST_HEAD(&cmd->eh_entry);
 
+       /*
+        * Set the serial numbers back to zero
+        */
+       cmd->serial_number = 0;
+
+       atomic_inc(&cmd->device->iodone_cnt);
+       if (cmd->result)
+               atomic_inc(&cmd->device->ioerr_cnt);
+
        disposition = scsi_decide_disposition(cmd);
        if (disposition != SUCCESS &&
            time_before(cmd->jiffies_at_alloc + wait_for, jiffies)) {
@@ -1675,6 +1684,7 @@ struct request_queue *scsi_alloc_queue(struct scsi_device *sdev)
 
        blk_queue_prep_rq(q, scsi_prep_fn);
        blk_queue_softirq_done(q, scsi_softirq_done);
+       blk_queue_rq_timed_out(q, scsi_times_out);
        return q;
 }
 
@@ -2064,10 +2074,13 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state)
 
        switch (state) {
        case SDEV_CREATED:
-               /* There are no legal states that come back to
-                * created.  This is the manually initialised start
-                * state */
-               goto illegal;
+               switch (oldstate) {
+               case SDEV_CREATED_BLOCK:
+                       break;
+               default:
+                       goto illegal;
+               }
+               break;
                        
        case SDEV_RUNNING:
                switch (oldstate) {
@@ -2105,8 +2118,17 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state)
 
        case SDEV_BLOCK:
                switch (oldstate) {
-               case SDEV_CREATED:
                case SDEV_RUNNING:
+               case SDEV_CREATED_BLOCK:
+                       break;
+               default:
+                       goto illegal;
+               }
+               break;
+
+       case SDEV_CREATED_BLOCK:
+               switch (oldstate) {
+               case SDEV_CREATED:
                        break;
                default:
                        goto illegal;
@@ -2394,8 +2416,12 @@ scsi_internal_device_block(struct scsi_device *sdev)
        int err = 0;
 
        err = scsi_device_set_state(sdev, SDEV_BLOCK);
-       if (err)
-               return err;
+       if (err) {
+               err = scsi_device_set_state(sdev, SDEV_CREATED_BLOCK);
+
+               if (err)
+                       return err;
+       }
 
        /* 
         * The device has transitioned to SDEV_BLOCK.  Stop the
@@ -2438,8 +2464,12 @@ scsi_internal_device_unblock(struct scsi_device *sdev)
         * and goose the device queue if successful.  
         */
        err = scsi_device_set_state(sdev, SDEV_RUNNING);
-       if (err)
-               return err;
+       if (err) {
+               err = scsi_device_set_state(sdev, SDEV_CREATED);
+
+               if (err)
+                       return err;
+       }
 
        spin_lock_irqsave(q->queue_lock, flags);
        blk_start_queue(q);
index ae7ed9a226623db41e1354a12c6f97d5d83bc324..b37e133de80557e3be96e70f0960d5ef910c1fb5 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/time.h>
 #include <linux/jiffies.h>
 #include <linux/security.h>
+#include <linux/delay.h>
 #include <net/sock.h>
 #include <net/netlink.h>
 
 struct sock *scsi_nl_sock = NULL;
 EXPORT_SYMBOL_GPL(scsi_nl_sock);
 
+static DEFINE_SPINLOCK(scsi_nl_lock);
+static struct list_head scsi_nl_drivers;
+
+static u32     scsi_nl_state;
+#define STATE_EHANDLER_BSY             0x00000001
+
+struct scsi_nl_transport {
+       int (*msg_handler)(struct sk_buff *);
+       void (*event_handler)(struct notifier_block *, unsigned long, void *);
+       unsigned int refcnt;
+       int flags;
+};
+
+/* flags values (bit flags) */
+#define HANDLER_DELETING               0x1
+
+static struct scsi_nl_transport transports[SCSI_NL_MAX_TRANSPORTS] =
+       { {NULL, }, };
+
+
+struct scsi_nl_drvr {
+       struct list_head next;
+       int (*dmsg_handler)(struct Scsi_Host *shost, void *payload,
+                                u32 len, u32 pid);
+       void (*devt_handler)(struct notifier_block *nb,
+                                unsigned long event, void *notify_ptr);
+       struct scsi_host_template *hostt;
+       u64 vendor_id;
+       unsigned int refcnt;
+       int flags;
+};
+
+
 
 /**
  * scsi_nl_rcv_msg - Receive message handler.
@@ -45,8 +79,9 @@ scsi_nl_rcv_msg(struct sk_buff *skb)
 {
        struct nlmsghdr *nlh;
        struct scsi_nl_hdr *hdr;
-       uint32_t rlen;
-       int err;
+       unsigned long flags;
+       u32 rlen;
+       int err, tport;
 
        while (skb->len >= NLMSG_SPACE(0)) {
                err = 0;
@@ -65,7 +100,7 @@ scsi_nl_rcv_msg(struct sk_buff *skb)
 
                if (nlh->nlmsg_type != SCSI_TRANSPORT_MSG) {
                        err = -EBADMSG;
-                       return;
+                       goto next_msg;
                }
 
                hdr = NLMSG_DATA(nlh);
@@ -83,12 +118,27 @@ scsi_nl_rcv_msg(struct sk_buff *skb)
                if (nlh->nlmsg_len < (sizeof(*nlh) + hdr->msglen)) {
                        printk(KERN_WARNING "%s: discarding partial message\n",
                                 __func__);
-                       return;
+                       goto next_msg;
                }
 
                /*
-                * We currently don't support anyone sending us a message
+                * Deliver message to the appropriate transport
                 */
+               spin_lock_irqsave(&scsi_nl_lock, flags);
+
+               tport = hdr->transport;
+               if ((tport < SCSI_NL_MAX_TRANSPORTS) &&
+                   !(transports[tport].flags & HANDLER_DELETING) &&
+                   (transports[tport].msg_handler)) {
+                       transports[tport].refcnt++;
+                       spin_unlock_irqrestore(&scsi_nl_lock, flags);
+                       err = transports[tport].msg_handler(skb);
+                       spin_lock_irqsave(&scsi_nl_lock, flags);
+                       transports[tport].refcnt--;
+               } else
+                       err = -ENOENT;
+
+               spin_unlock_irqrestore(&scsi_nl_lock, flags);
 
 next_msg:
                if ((err) || (nlh->nlmsg_flags & NLM_F_ACK))
@@ -110,14 +160,42 @@ static int
 scsi_nl_rcv_event(struct notifier_block *this, unsigned long event, void *ptr)
 {
        struct netlink_notify *n = ptr;
+       struct scsi_nl_drvr *driver;
+       unsigned long flags;
+       int tport;
 
        if (n->protocol != NETLINK_SCSITRANSPORT)
                return NOTIFY_DONE;
 
+       spin_lock_irqsave(&scsi_nl_lock, flags);
+       scsi_nl_state |= STATE_EHANDLER_BSY;
+
        /*
-        * Currently, we are not tracking PID's, etc. There is nothing
-        * to handle.
+        * Pass event on to any transports that may be listening
         */
+       for (tport = 0; tport < SCSI_NL_MAX_TRANSPORTS; tport++) {
+               if (!(transports[tport].flags & HANDLER_DELETING) &&
+                   (transports[tport].event_handler)) {
+                       spin_unlock_irqrestore(&scsi_nl_lock, flags);
+                       transports[tport].event_handler(this, event, ptr);
+                       spin_lock_irqsave(&scsi_nl_lock, flags);
+               }
+       }
+
+       /*
+        * Pass event on to any drivers that may be listening
+        */
+       list_for_each_entry(driver, &scsi_nl_drivers, next) {
+               if (!(driver->flags & HANDLER_DELETING) &&
+                   (driver->devt_handler)) {
+                       spin_unlock_irqrestore(&scsi_nl_lock, flags);
+                       driver->devt_handler(this, event, ptr);
+                       spin_lock_irqsave(&scsi_nl_lock, flags);
+               }
+       }
+
+       scsi_nl_state &= ~STATE_EHANDLER_BSY;
+       spin_unlock_irqrestore(&scsi_nl_lock, flags);
 
        return NOTIFY_DONE;
 }
@@ -128,7 +206,281 @@ static struct notifier_block scsi_netlink_notifier = {
 
 
 /**
- * scsi_netlink_init - Called by SCSI subsystem to intialize the SCSI transport netlink interface
+ * GENERIC SCSI transport receive and event handlers
+ **/
+
+/**
+ * scsi_generic_msg_handler - receive message handler for GENERIC transport
+ *                      messages
+ *
+ * @skb:               socket receive buffer
+ *
+ **/
+static int
+scsi_generic_msg_handler(struct sk_buff *skb)
+{
+       struct nlmsghdr *nlh = nlmsg_hdr(skb);
+       struct scsi_nl_hdr *snlh = NLMSG_DATA(nlh);
+       struct scsi_nl_drvr *driver;
+       struct Scsi_Host *shost;
+       unsigned long flags;
+       int err = 0, match, pid;
+
+       pid = NETLINK_CREDS(skb)->pid;
+
+       switch (snlh->msgtype) {
+       case SCSI_NL_SHOST_VENDOR:
+               {
+               struct scsi_nl_host_vendor_msg *msg = NLMSG_DATA(nlh);
+
+               /* Locate the driver that corresponds to the message */
+               spin_lock_irqsave(&scsi_nl_lock, flags);
+               match = 0;
+               list_for_each_entry(driver, &scsi_nl_drivers, next) {
+                       if (driver->vendor_id == msg->vendor_id) {
+                               match = 1;
+                               break;
+                       }
+               }
+
+               if ((!match) || (!driver->dmsg_handler)) {
+                       spin_unlock_irqrestore(&scsi_nl_lock, flags);
+                       err = -ESRCH;
+                       goto rcv_exit;
+               }
+
+               if (driver->flags & HANDLER_DELETING) {
+                       spin_unlock_irqrestore(&scsi_nl_lock, flags);
+                       err = -ESHUTDOWN;
+                       goto rcv_exit;
+               }
+
+               driver->refcnt++;
+               spin_unlock_irqrestore(&scsi_nl_lock, flags);
+
+
+               /* if successful, scsi_host_lookup takes a shost reference */
+               shost = scsi_host_lookup(msg->host_no);
+               if (!shost) {
+                       err = -ENODEV;
+                       goto driver_exit;
+               }
+
+               /* is this host owned by the vendor ? */
+               if (shost->hostt != driver->hostt) {
+                       err = -EINVAL;
+                       goto vendormsg_put;
+               }
+
+               /* pass message on to the driver */
+               err = driver->dmsg_handler(shost, (void *)&msg[1],
+                                        msg->vmsg_datalen, pid);
+
+vendormsg_put:
+               /* release reference by scsi_host_lookup */
+               scsi_host_put(shost);
+
+driver_exit:
+               /* release our own reference on the registration object */
+               spin_lock_irqsave(&scsi_nl_lock, flags);
+               driver->refcnt--;
+               spin_unlock_irqrestore(&scsi_nl_lock, flags);
+               break;
+               }
+
+       default:
+               err = -EBADR;
+               break;
+       }
+
+rcv_exit:
+       if (err)
+               printk(KERN_WARNING "%s: Msgtype %d failed - err %d\n",
+                        __func__, snlh->msgtype, err);
+       return err;
+}
+
+
+/**
+ * scsi_nl_add_transport -
+ *    Registers message and event handlers for a transport. Enables
+ *    receipt of netlink messages and events to a transport.
+ *
+ * @tport:             transport registering handlers
+ * @msg_handler:       receive message handler callback
+ * @event_handler:     receive event handler callback
+ **/
+int
+scsi_nl_add_transport(u8 tport,
+       int (*msg_handler)(struct sk_buff *),
+       void (*event_handler)(struct notifier_block *, unsigned long, void *))
+{
+       unsigned long flags;
+       int err = 0;
+
+       if (tport >= SCSI_NL_MAX_TRANSPORTS)
+               return -EINVAL;
+
+       spin_lock_irqsave(&scsi_nl_lock, flags);
+
+       if (scsi_nl_state & STATE_EHANDLER_BSY) {
+               spin_unlock_irqrestore(&scsi_nl_lock, flags);
+               msleep(1);
+               spin_lock_irqsave(&scsi_nl_lock, flags);
+       }
+
+       if (transports[tport].msg_handler || transports[tport].event_handler) {
+               err = -EALREADY;
+               goto register_out;
+       }
+
+       transports[tport].msg_handler = msg_handler;
+       transports[tport].event_handler = event_handler;
+       transports[tport].flags = 0;
+       transports[tport].refcnt = 0;
+
+register_out:
+       spin_unlock_irqrestore(&scsi_nl_lock, flags);
+
+       return err;
+}
+EXPORT_SYMBOL_GPL(scsi_nl_add_transport);
+
+
+/**
+ * scsi_nl_remove_transport -
+ *    Disable transport receiption of messages and events
+ *
+ * @tport:             transport deregistering handlers
+ *
+ **/
+void
+scsi_nl_remove_transport(u8 tport)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&scsi_nl_lock, flags);
+       if (scsi_nl_state & STATE_EHANDLER_BSY) {
+               spin_unlock_irqrestore(&scsi_nl_lock, flags);
+               msleep(1);
+               spin_lock_irqsave(&scsi_nl_lock, flags);
+       }
+
+       if (tport < SCSI_NL_MAX_TRANSPORTS) {
+               transports[tport].flags |= HANDLER_DELETING;
+
+               while (transports[tport].refcnt != 0) {
+                       spin_unlock_irqrestore(&scsi_nl_lock, flags);
+                       schedule_timeout_uninterruptible(HZ/4);
+                       spin_lock_irqsave(&scsi_nl_lock, flags);
+               }
+               transports[tport].msg_handler = NULL;
+               transports[tport].event_handler = NULL;
+               transports[tport].flags = 0;
+       }
+
+       spin_unlock_irqrestore(&scsi_nl_lock, flags);
+
+       return;
+}
+EXPORT_SYMBOL_GPL(scsi_nl_remove_transport);
+
+
+/**
+ * scsi_nl_add_driver -
+ *    A driver is registering its interfaces for SCSI netlink messages
+ *
+ * @vendor_id:          A unique identification value for the driver.
+ * @hostt:             address of the driver's host template. Used
+ *                     to verify an shost is bound to the driver
+ * @nlmsg_handler:     receive message handler callback
+ * @nlevt_handler:     receive event handler callback
+ *
+ * Returns:
+ *   0 on Success
+ *   error result otherwise
+ **/
+int
+scsi_nl_add_driver(u64 vendor_id, struct scsi_host_template *hostt,
+       int (*nlmsg_handler)(struct Scsi_Host *shost, void *payload,
+                                u32 len, u32 pid),
+       void (*nlevt_handler)(struct notifier_block *nb,
+                                unsigned long event, void *notify_ptr))
+{
+       struct scsi_nl_drvr *driver;
+       unsigned long flags;
+
+       driver = kzalloc(sizeof(*driver), GFP_KERNEL);
+       if (unlikely(!driver)) {
+               printk(KERN_ERR "%s: allocation failure\n", __func__);
+               return -ENOMEM;
+       }
+
+       driver->dmsg_handler = nlmsg_handler;
+       driver->devt_handler = nlevt_handler;
+       driver->hostt = hostt;
+       driver->vendor_id = vendor_id;
+
+       spin_lock_irqsave(&scsi_nl_lock, flags);
+       if (scsi_nl_state & STATE_EHANDLER_BSY) {
+               spin_unlock_irqrestore(&scsi_nl_lock, flags);
+               msleep(1);
+               spin_lock_irqsave(&scsi_nl_lock, flags);
+       }
+       list_add_tail(&driver->next, &scsi_nl_drivers);
+       spin_unlock_irqrestore(&scsi_nl_lock, flags);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(scsi_nl_add_driver);
+
+
+/**
+ * scsi_nl_remove_driver -
+ *    An driver is unregistering with the SCSI netlink messages
+ *
+ * @vendor_id:          The unique identification value for the driver.
+ **/
+void
+scsi_nl_remove_driver(u64 vendor_id)
+{
+       struct scsi_nl_drvr *driver;
+       unsigned long flags;
+
+       spin_lock_irqsave(&scsi_nl_lock, flags);
+       if (scsi_nl_state & STATE_EHANDLER_BSY) {
+               spin_unlock_irqrestore(&scsi_nl_lock, flags);
+               msleep(1);
+               spin_lock_irqsave(&scsi_nl_lock, flags);
+       }
+
+       list_for_each_entry(driver, &scsi_nl_drivers, next) {
+               if (driver->vendor_id == vendor_id) {
+                       driver->flags |= HANDLER_DELETING;
+                       while (driver->refcnt != 0) {
+                               spin_unlock_irqrestore(&scsi_nl_lock, flags);
+                               schedule_timeout_uninterruptible(HZ/4);
+                               spin_lock_irqsave(&scsi_nl_lock, flags);
+                       }
+                       list_del(&driver->next);
+                       kfree(driver);
+                       spin_unlock_irqrestore(&scsi_nl_lock, flags);
+                       return;
+               }
+       }
+
+       spin_unlock_irqrestore(&scsi_nl_lock, flags);
+
+       printk(KERN_ERR "%s: removal of driver failed - vendor_id 0x%llx\n",
+              __func__, (unsigned long long)vendor_id);
+       return;
+}
+EXPORT_SYMBOL_GPL(scsi_nl_remove_driver);
+
+
+/**
+ * scsi_netlink_init - Called by SCSI subsystem to intialize
+ *     the SCSI transport netlink interface
  *
  **/
 void
@@ -136,6 +488,8 @@ scsi_netlink_init(void)
 {
        int error;
 
+       INIT_LIST_HEAD(&scsi_nl_drivers);
+
        error = netlink_register_notifier(&scsi_netlink_notifier);
        if (error) {
                printk(KERN_ERR "%s: register of event handler failed - %d\n",
@@ -150,8 +504,15 @@ scsi_netlink_init(void)
                printk(KERN_ERR "%s: register of recieve handler failed\n",
                                __func__);
                netlink_unregister_notifier(&scsi_netlink_notifier);
+               return;
        }
 
+       /* Register the entry points for the generic SCSI transport */
+       error = scsi_nl_add_transport(SCSI_NL_TRANSPORT,
+                               scsi_generic_msg_handler, NULL);
+       if (error)
+               printk(KERN_ERR "%s: register of GENERIC transport handler"
+                               "  failed - %d\n", __func__, error);
        return;
 }
 
@@ -163,6 +524,8 @@ scsi_netlink_init(void)
 void
 scsi_netlink_exit(void)
 {
+       scsi_nl_remove_transport(SCSI_NL_TRANSPORT);
+
        if (scsi_nl_sock) {
                netlink_kernel_release(scsi_nl_sock);
                netlink_unregister_notifier(&scsi_netlink_notifier);
@@ -172,3 +535,147 @@ scsi_netlink_exit(void)
 }
 
 
+/*
+ * Exported Interfaces
+ */
+
+/**
+ * scsi_nl_send_transport_msg -
+ *    Generic function to send a single message from a SCSI transport to
+ *    a single process
+ *
+ * @pid:               receiving pid
+ * @hdr:               message payload
+ *
+ **/
+void
+scsi_nl_send_transport_msg(u32 pid, struct scsi_nl_hdr *hdr)
+{
+       struct sk_buff *skb;
+       struct nlmsghdr *nlh;
+       const char *fn;
+       char *datab;
+       u32 len, skblen;
+       int err;
+
+       if (!scsi_nl_sock) {
+               err = -ENOENT;
+               fn = "netlink socket";
+               goto msg_fail;
+       }
+
+       len = NLMSG_SPACE(hdr->msglen);
+       skblen = NLMSG_SPACE(len);
+
+       skb = alloc_skb(skblen, GFP_KERNEL);
+       if (!skb) {
+               err = -ENOBUFS;
+               fn = "alloc_skb";
+               goto msg_fail;
+       }
+
+       nlh = nlmsg_put(skb, pid, 0, SCSI_TRANSPORT_MSG, len - sizeof(*nlh), 0);
+       if (!nlh) {
+               err = -ENOBUFS;
+               fn = "nlmsg_put";
+               goto msg_fail_skb;
+       }
+       datab = NLMSG_DATA(nlh);
+       memcpy(datab, hdr, hdr->msglen);
+
+       err = nlmsg_unicast(scsi_nl_sock, skb, pid);
+       if (err < 0) {
+               fn = "nlmsg_unicast";
+               /* nlmsg_unicast already kfree_skb'd */
+               goto msg_fail;
+       }
+
+       return;
+
+msg_fail_skb:
+       kfree_skb(skb);
+msg_fail:
+       printk(KERN_WARNING
+               "%s: Dropped Message : pid %d Transport %d, msgtype x%x, "
+               "msglen %d: %s : err %d\n",
+               __func__, pid, hdr->transport, hdr->msgtype, hdr->msglen,
+               fn, err);
+       return;
+}
+EXPORT_SYMBOL_GPL(scsi_nl_send_transport_msg);
+
+
+/**
+ * scsi_nl_send_vendor_msg - called to send a shost vendor unique message
+ *                      to a specific process id.
+ *
+ * @pid:               process id of the receiver
+ * @host_no:           host # sending the message
+ * @vendor_id:         unique identifier for the driver's vendor
+ * @data_len:          amount, in bytes, of vendor unique payload data
+ * @data_buf:          pointer to vendor unique data buffer
+ *
+ * Returns:
+ *   0 on succesful return
+ *   otherwise, failing error code
+ *
+ * Notes:
+ *     This routine assumes no locks are held on entry.
+ */
+int
+scsi_nl_send_vendor_msg(u32 pid, unsigned short host_no, u64 vendor_id,
+                        char *data_buf, u32 data_len)
+{
+       struct sk_buff *skb;
+       struct nlmsghdr *nlh;
+       struct scsi_nl_host_vendor_msg *msg;
+       u32 len, skblen;
+       int err;
+
+       if (!scsi_nl_sock) {
+               err = -ENOENT;
+               goto send_vendor_fail;
+       }
+
+       len = SCSI_NL_MSGALIGN(sizeof(*msg) + data_len);
+       skblen = NLMSG_SPACE(len);
+
+       skb = alloc_skb(skblen, GFP_KERNEL);
+       if (!skb) {
+               err = -ENOBUFS;
+               goto send_vendor_fail;
+       }
+
+       nlh = nlmsg_put(skb, 0, 0, SCSI_TRANSPORT_MSG,
+                               skblen - sizeof(*nlh), 0);
+       if (!nlh) {
+               err = -ENOBUFS;
+               goto send_vendor_fail_skb;
+       }
+       msg = NLMSG_DATA(nlh);
+
+       INIT_SCSI_NL_HDR(&msg->snlh, SCSI_NL_TRANSPORT,
+                               SCSI_NL_SHOST_VENDOR, len);
+       msg->vendor_id = vendor_id;
+       msg->host_no = host_no;
+       msg->vmsg_datalen = data_len;   /* bytes */
+       memcpy(&msg[1], data_buf, data_len);
+
+       err = nlmsg_unicast(scsi_nl_sock, skb, pid);
+       if (err)
+               /* nlmsg_multicast already kfree_skb'd */
+               goto send_vendor_fail;
+
+       return 0;
+
+send_vendor_fail_skb:
+       kfree_skb(skb);
+send_vendor_fail:
+       printk(KERN_WARNING
+               "%s: Dropped SCSI Msg : host %d vendor_unique - err %d\n",
+               __func__, host_no, err);
+       return err;
+}
+EXPORT_SYMBOL(scsi_nl_send_vendor_msg);
+
+
index 79f0f7511204594186a36bae6e62acb4c3cd1a9c..6cddd5dd323cbb578af7bd3bc8209bc1b9ce7736 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/device.h>
 
 struct request_queue;
+struct request;
 struct scsi_cmnd;
 struct scsi_device;
 struct scsi_host_template;
@@ -27,7 +28,6 @@ extern void scsi_exit_hosts(void);
 extern int scsi_dispatch_cmd(struct scsi_cmnd *cmd);
 extern int scsi_setup_command_freelist(struct Scsi_Host *shost);
 extern void scsi_destroy_command_freelist(struct Scsi_Host *shost);
-extern void __scsi_done(struct scsi_cmnd *cmd);
 #ifdef CONFIG_SCSI_LOGGING
 void scsi_log_send(struct scsi_cmnd *cmd);
 void scsi_log_completion(struct scsi_cmnd *cmd, int disposition);
@@ -49,10 +49,7 @@ extern int __init scsi_init_devinfo(void);
 extern void scsi_exit_devinfo(void);
 
 /* scsi_error.c */
-extern void scsi_add_timer(struct scsi_cmnd *, int,
-               void (*)(struct scsi_cmnd *));
-extern int scsi_delete_timer(struct scsi_cmnd *);
-extern void scsi_times_out(struct scsi_cmnd *cmd);
+extern enum blk_eh_timer_return scsi_times_out(struct request *req);
 extern int scsi_error_handler(void *host);
 extern int scsi_decide_disposition(struct scsi_cmnd *cmd);
 extern void scsi_eh_wakeup(struct Scsi_Host *shost);
index c6a904a45bf9871677e50ea762ceaf3c468ae049..82f7b2dd08a23e934aa4d6e08ce76e3c84ab1dc4 100644 (file)
@@ -259,8 +259,8 @@ static int scsi_add_single_device(uint host, uint channel, uint id, uint lun)
        int error = -ENXIO;
 
        shost = scsi_host_lookup(host);
-       if (IS_ERR(shost))
-               return PTR_ERR(shost);
+       if (!shost)
+               return error;
 
        if (shost->transportt->user_scan)
                error = shost->transportt->user_scan(shost, channel, id, lun);
@@ -287,8 +287,8 @@ static int scsi_remove_single_device(uint host, uint channel, uint id, uint lun)
        int error = -ENXIO;
 
        shost = scsi_host_lookup(host);
-       if (IS_ERR(shost))
-               return PTR_ERR(shost);
+       if (!shost)
+               return error;
        sdev = scsi_device_lookup(shost, channel, id, lun);
        if (sdev) {
                scsi_remove_device(sdev);
index 34d0de6cd51123cb42d7cda2bc4b62a2f5151c9b..334862e26a1b75d3d7cb01f9cff9811ecfa81046 100644 (file)
@@ -730,6 +730,8 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
 static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
                int *bflags, int async)
 {
+       int ret;
+
        /*
         * XXX do not save the inquiry, since it can change underneath us,
         * save just vendor/model/rev.
@@ -885,7 +887,17 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
 
        /* set the device running here so that slave configure
         * may do I/O */
-       scsi_device_set_state(sdev, SDEV_RUNNING);
+       ret = scsi_device_set_state(sdev, SDEV_RUNNING);
+       if (ret) {
+               ret = scsi_device_set_state(sdev, SDEV_BLOCK);
+
+               if (ret) {
+                       sdev_printk(KERN_ERR, sdev,
+                                   "in wrong state %s to complete scan\n",
+                                   scsi_device_state_name(sdev->sdev_state));
+                       return SCSI_SCAN_NO_RESPONSE;
+               }
+       }
 
        if (*bflags & BLIST_MS_192_BYTES_FOR_3F)
                sdev->use_192_bytes_for_3f = 1;
@@ -899,7 +911,7 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
        transport_configure_device(&sdev->sdev_gendev);
 
        if (sdev->host->hostt->slave_configure) {
-               int ret = sdev->host->hostt->slave_configure(sdev);
+               ret = sdev->host->hostt->slave_configure(sdev);
                if (ret) {
                        /*
                         * if LLDD reports slave not present, don't clutter
@@ -994,7 +1006,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
         */
        sdev = scsi_device_lookup_by_target(starget, lun);
        if (sdev) {
-               if (rescan || sdev->sdev_state != SDEV_CREATED) {
+               if (rescan || !scsi_device_created(sdev)) {
                        SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO
                                "scsi scan: device exists on %s\n",
                                sdev->sdev_gendev.bus_id));
@@ -1467,7 +1479,7 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
        kfree(lun_data);
  out:
        scsi_device_put(sdev);
-       if (sdev->sdev_state == SDEV_CREATED)
+       if (scsi_device_created(sdev))
                /*
                 * the sdev we used didn't appear in the report luns scan
                 */
index ab3c71869be55d9deeb8ca101c59faf80e140561..93c28f30bbd75e8111dff7bf278667439e4d508f 100644 (file)
@@ -34,6 +34,7 @@ static const struct {
        { SDEV_QUIESCE, "quiesce" },
        { SDEV_OFFLINE, "offline" },
        { SDEV_BLOCK,   "blocked" },
+       { SDEV_CREATED_BLOCK, "created-blocked" },
 };
 
 const char *scsi_device_state_name(enum scsi_device_state state)
@@ -560,12 +561,15 @@ sdev_rd_attr (vendor, "%.8s\n");
 sdev_rd_attr (model, "%.16s\n");
 sdev_rd_attr (rev, "%.4s\n");
 
+/*
+ * TODO: can we make these symlinks to the block layer ones?
+ */
 static ssize_t
 sdev_show_timeout (struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct scsi_device *sdev;
        sdev = to_scsi_device(dev);
-       return snprintf (buf, 20, "%d\n", sdev->timeout / HZ);
+       return snprintf(buf, 20, "%d\n", sdev->request_queue->rq_timeout / HZ);
 }
 
 static ssize_t
@@ -576,7 +580,7 @@ sdev_store_timeout (struct device *dev, struct device_attribute *attr,
        int timeout;
        sdev = to_scsi_device(dev);
        sscanf (buf, "%d\n", &timeout);
-       sdev->timeout = timeout * HZ;
+       blk_queue_rq_timeout(sdev->request_queue, timeout * HZ);
        return count;
 }
 static DEVICE_ATTR(timeout, S_IRUGO | S_IWUSR, sdev_show_timeout, sdev_store_timeout);
index 257e097c39afe708e2e5a4286948e0de246c5c92..48ba413f7f6afb511f9d0c26daa42a5cb34dce77 100644 (file)
@@ -362,7 +362,7 @@ static int scsi_map_user_pages(struct scsi_tgt_cmd *tcmd, struct scsi_cmnd *cmd,
        int err;
 
        dprintk("%lx %u\n", uaddr, len);
-       err = blk_rq_map_user(q, rq, (void *)uaddr, len);
+       err = blk_rq_map_user(q, rq, NULL, (void *)uaddr, len, GFP_KERNEL);
        if (err) {
                /*
                 * TODO: need to fixup sg_tablesize, max_segment_size,
@@ -460,7 +460,7 @@ int scsi_tgt_kspace_exec(int host_no, u64 itn_id, int result, u64 tag,
 
        /* TODO: replace with a O(1) alg */
        shost = scsi_host_lookup(host_no);
-       if (IS_ERR(shost)) {
+       if (!shost) {
                printk(KERN_ERR "Could not find host no %d\n", host_no);
                return -EINVAL;
        }
@@ -550,7 +550,7 @@ int scsi_tgt_kspace_tsk_mgmt(int host_no, u64 itn_id, u64 mid, int result)
        dprintk("%d %d %llx\n", host_no, result, (unsigned long long) mid);
 
        shost = scsi_host_lookup(host_no);
-       if (IS_ERR(shost)) {
+       if (!shost) {
                printk(KERN_ERR "Could not find host no %d\n", host_no);
                return err;
        }
@@ -603,7 +603,7 @@ int scsi_tgt_kspace_it_nexus_rsp(int host_no, u64 itn_id, int result)
        dprintk("%d %d%llx\n", host_no, result, (unsigned long long)itn_id);
 
        shost = scsi_host_lookup(host_no);
-       if (IS_ERR(shost)) {
+       if (!shost) {
                printk(KERN_ERR "Could not find host no %d\n", host_no);
                return err;
        }
index 56823fd1fb8418811da8fc4418ec271b846b65da..d5f7653bb94bad8b4fd559b54fe2cc7bca1cf28c 100644 (file)
 
 static int fc_queue_work(struct Scsi_Host *, struct work_struct *);
 static void fc_vport_sched_delete(struct work_struct *work);
-
-/*
- * This is a temporary carrier for creating a vport. It will eventually
- * be replaced  by a real message definition for sgio or netlink.
- *
- * fc_vport_identifiers: This set of data contains all elements
- * to uniquely identify and instantiate a FC virtual port.
- *
- * Notes:
- *   symbolic_name: The driver is to append the symbolic_name string data
- *      to the symbolic_node_name data that it generates by default.
- *      the resulting combination should then be registered with the switch.
- *      It is expected that things like Xen may stuff a VM title into
- *      this field.
- */
-struct fc_vport_identifiers {
-       u64 node_name;
-       u64 port_name;
-       u32 roles;
-       bool disable;
-       enum fc_port_type vport_type;   /* only FC_PORTTYPE_NPIV allowed */
-       char symbolic_name[FC_VPORT_SYMBOLIC_NAMELEN];
-};
-
-static int fc_vport_create(struct Scsi_Host *shost, int channel,
+static int fc_vport_setup(struct Scsi_Host *shost, int channel,
        struct device *pdev, struct fc_vport_identifiers  *ids,
        struct fc_vport **vport);
 
@@ -1760,7 +1736,7 @@ store_fc_host_vport_create(struct device *dev, struct device_attribute *attr,
        vid.disable = false;            /* always enabled */
 
        /* we only allow support on Channel 0 !!! */
-       stat = fc_vport_create(shost, 0, &shost->shost_gendev, &vid, &vport);
+       stat = fc_vport_setup(shost, 0, &shost->shost_gendev, &vid, &vport);
        return stat ? stat : count;
 }
 static FC_DEVICE_ATTR(host, vport_create, S_IWUSR, NULL,
@@ -1950,15 +1926,15 @@ static int fc_vport_match(struct attribute_container *cont,
  * Notes:
  *     This routine assumes no locks are held on entry.
  */
-static enum scsi_eh_timer_return
+static enum blk_eh_timer_return
 fc_timed_out(struct scsi_cmnd *scmd)
 {
        struct fc_rport *rport = starget_to_rport(scsi_target(scmd->device));
 
        if (rport->port_state == FC_PORTSTATE_BLOCKED)
-               return EH_RESET_TIMER;
+               return BLK_EH_RESET_TIMER;
 
-       return EH_NOT_HANDLED;
+       return BLK_EH_NOT_HANDLED;
 }
 
 /*
@@ -3103,7 +3079,7 @@ fc_scsi_scan_rport(struct work_struct *work)
 
 
 /**
- * fc_vport_create - allocates and creates a FC virtual port.
+ * fc_vport_setup - allocates and creates a FC virtual port.
  * @shost:     scsi host the virtual port is connected to.
  * @channel:   Channel on shost port connected to.
  * @pdev:      parent device for vport
@@ -3118,7 +3094,7 @@ fc_scsi_scan_rport(struct work_struct *work)
  *     This routine assumes no locks are held on entry.
  */
 static int
-fc_vport_create(struct Scsi_Host *shost, int channel, struct device *pdev,
+fc_vport_setup(struct Scsi_Host *shost, int channel, struct device *pdev,
        struct fc_vport_identifiers  *ids, struct fc_vport **ret_vport)
 {
        struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
@@ -3231,6 +3207,28 @@ delete_vport:
        return error;
 }
 
+/**
+ * fc_vport_create - Admin App or LLDD requests creation of a vport
+ * @shost:     scsi host the virtual port is connected to.
+ * @channel:   channel on shost port connected to.
+ * @ids:       The world wide names, FC4 port roles, etc for
+ *              the virtual port.
+ *
+ * Notes:
+ *     This routine assumes no locks are held on entry.
+ */
+struct fc_vport *
+fc_vport_create(struct Scsi_Host *shost, int channel,
+       struct fc_vport_identifiers *ids)
+{
+       int stat;
+       struct fc_vport *vport;
+
+       stat = fc_vport_setup(shost, channel, &shost->shost_gendev,
+                ids, &vport);
+       return stat ? NULL : vport;
+}
+EXPORT_SYMBOL(fc_vport_create);
 
 /**
  * fc_vport_terminate - Admin App or LLDD requests termination of a vport
index 043c3921164ff781f3b20e51232ee091d2381622..0ce5f7cdfe2a182a1e4216377e58476b6e2f1809 100644 (file)
@@ -1361,7 +1361,7 @@ iscsi_tgt_dscvr(struct iscsi_transport *transport,
                return -EINVAL;
 
        shost = scsi_host_lookup(ev->u.tgt_dscvr.host_no);
-       if (IS_ERR(shost)) {
+       if (!shost) {
                printk(KERN_ERR "target discovery could not find host no %u\n",
                       ev->u.tgt_dscvr.host_no);
                return -ENODEV;
@@ -1387,7 +1387,7 @@ iscsi_set_host_param(struct iscsi_transport *transport,
                return -ENOSYS;
 
        shost = scsi_host_lookup(ev->u.set_host_param.host_no);
-       if (IS_ERR(shost)) {
+       if (!shost) {
                printk(KERN_ERR "set_host_param could not find host no %u\n",
                       ev->u.set_host_param.host_no);
                return -ENODEV;
index e5e7d78564545543925fc6136c6e7c7fc994c028..a7b53be633676399e3a08b6a6113a2b95da7cc6e 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/blkpg.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
+#include <linux/string_helpers.h>
 #include <asm/uaccess.h>
 
 #include <scsi/scsi.h>
@@ -86,6 +87,12 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_DISK);
 MODULE_ALIAS_SCSI_DEVICE(TYPE_MOD);
 MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC);
 
+#if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT)
+#define SD_MINORS      16
+#else
+#define SD_MINORS      0
+#endif
+
 static int  sd_revalidate_disk(struct gendisk *);
 static int  sd_probe(struct device *);
 static int  sd_remove(struct device *);
@@ -159,7 +166,7 @@ sd_store_cache_type(struct device *dev, struct device_attribute *attr,
                        sd_print_sense_hdr(sdkp, &sshdr);
                return -EINVAL;
        }
-       sd_revalidate_disk(sdkp->disk);
+       revalidate_disk(sdkp->disk);
        return count;
 }
 
@@ -377,7 +384,6 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
        sector_t block = rq->sector;
        sector_t threshold;
        unsigned int this_count = rq->nr_sectors;
-       unsigned int timeout = sdp->timeout;
        int ret;
 
        if (rq->cmd_type == REQ_TYPE_BLOCK_PC) {
@@ -578,7 +584,6 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
        SCpnt->transfersize = sdp->sector_size;
        SCpnt->underflow = this_count << 9;
        SCpnt->allowed = SD_MAX_RETRIES;
-       SCpnt->timeout_per_command = timeout;
 
        /*
         * This indicates that the command is ready from our end to be
@@ -910,7 +915,7 @@ static void sd_rescan(struct device *dev)
        struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
 
        if (sdkp) {
-               sd_revalidate_disk(sdkp->disk);
+               revalidate_disk(sdkp->disk);
                scsi_disk_put(sdkp);
        }
 }
@@ -1429,27 +1434,21 @@ got_data:
                 */
                sector_size = 512;
        }
+       blk_queue_hardsect_size(sdp->request_queue, sector_size);
+
        {
-               /*
-                * The msdos fs needs to know the hardware sector size
-                * So I have created this table. See ll_rw_blk.c
-                * Jacques Gelinas (Jacques@solucorp.qc.ca)
-                */
-               int hard_sector = sector_size;
-               sector_t sz = (sdkp->capacity/2) * (hard_sector/256);
-               struct request_queue *queue = sdp->request_queue;
-               sector_t mb = sz;
+               char cap_str_2[10], cap_str_10[10];
+               u64 sz = sdkp->capacity << ffz(~sector_size);
 
-               blk_queue_hardsect_size(queue, hard_sector);
-               /* avoid 64-bit division on 32-bit platforms */
-               sector_div(sz, 625);
-               mb -= sz - 974;
-               sector_div(mb, 1950);
+               string_get_size(sz, STRING_UNITS_2, cap_str_2,
+                               sizeof(cap_str_2));
+               string_get_size(sz, STRING_UNITS_10, cap_str_10,
+                               sizeof(cap_str_10));
 
                sd_printk(KERN_NOTICE, sdkp,
-                         "%llu %d-byte hardware sectors (%llu MB)\n",
+                         "%llu %d-byte hardware sectors: (%s/%s)\n",
                          (unsigned long long)sdkp->capacity,
-                         hard_sector, (unsigned long long)mb);
+                         sector_size, cap_str_10, cap_str_2);
        }
 
        /* Rescale capacity to 512-byte units */
@@ -1763,6 +1762,52 @@ static int sd_revalidate_disk(struct gendisk *disk)
        return 0;
 }
 
+/**
+ *     sd_format_disk_name - format disk name
+ *     @prefix: name prefix - ie. "sd" for SCSI disks
+ *     @index: index of the disk to format name for
+ *     @buf: output buffer
+ *     @buflen: length of the output buffer
+ *
+ *     SCSI disk names starts at sda.  The 26th device is sdz and the
+ *     27th is sdaa.  The last one for two lettered suffix is sdzz
+ *     which is followed by sdaaa.
+ *
+ *     This is basically 26 base counting with one extra 'nil' entry
+ *     at the beggining from the second digit on and can be
+ *     determined using similar method as 26 base conversion with the
+ *     index shifted -1 after each digit is computed.
+ *
+ *     CONTEXT:
+ *     Don't care.
+ *
+ *     RETURNS:
+ *     0 on success, -errno on failure.
+ */
+static int sd_format_disk_name(char *prefix, int index, char *buf, int buflen)
+{
+       const int base = 'z' - 'a' + 1;
+       char *begin = buf + strlen(prefix);
+       char *end = buf + buflen;
+       char *p;
+       int unit;
+
+       p = end - 1;
+       *p = '\0';
+       unit = base;
+       do {
+               if (p == begin)
+                       return -EINVAL;
+               *--p = 'a' + (index % unit);
+               index = (index / unit) - 1;
+       } while (index >= 0);
+
+       memmove(begin, p, end - p);
+       memcpy(buf, prefix, strlen(prefix));
+
+       return 0;
+}
+
 /**
  *     sd_probe - called during driver initialization and whenever a
  *     new scsi device is attached to the system. It is called once
@@ -1801,7 +1846,7 @@ static int sd_probe(struct device *dev)
        if (!sdkp)
                goto out;
 
-       gd = alloc_disk(16);
+       gd = alloc_disk(SD_MINORS);
        if (!gd)
                goto out_free;
 
@@ -1815,8 +1860,8 @@ static int sd_probe(struct device *dev)
        if (error)
                goto out_put;
 
-       error = -EBUSY;
-       if (index >= SD_MAX_DISKS)
+       error = sd_format_disk_name("sd", index, gd->disk_name, DISK_NAME_LEN);
+       if (error)
                goto out_free_index;
 
        sdkp->device = sdp;
@@ -1826,11 +1871,12 @@ static int sd_probe(struct device *dev)
        sdkp->openers = 0;
        sdkp->previous_state = 1;
 
-       if (!sdp->timeout) {
+       if (!sdp->request_queue->rq_timeout) {
                if (sdp->type != TYPE_MOD)
-                       sdp->timeout = SD_TIMEOUT;
+                       blk_queue_rq_timeout(sdp->request_queue, SD_TIMEOUT);
                else
-                       sdp->timeout = SD_MOD_TIMEOUT;
+                       blk_queue_rq_timeout(sdp->request_queue,
+                                            SD_MOD_TIMEOUT);
        }
 
        device_initialize(&sdkp->dev);
@@ -1843,24 +1889,12 @@ static int sd_probe(struct device *dev)
 
        get_device(&sdp->sdev_gendev);
 
-       gd->major = sd_major((index & 0xf0) >> 4);
-       gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00);
-       gd->minors = 16;
-       gd->fops = &sd_fops;
-
-       if (index < 26) {
-               sprintf(gd->disk_name, "sd%c", 'a' + index % 26);
-       } else if (index < (26 + 1) * 26) {
-               sprintf(gd->disk_name, "sd%c%c",
-                       'a' + index / 26 - 1,'a' + index % 26);
-       } else {
-               const unsigned int m1 = (index / 26 - 1) / 26 - 1;
-               const unsigned int m2 = (index / 26 - 1) % 26;
-               const unsigned int m3 =  index % 26;
-               sprintf(gd->disk_name, "sd%c%c%c",
-                       'a' + m1, 'a' + m2, 'a' + m3);
+       if (index < SD_MAX_DISKS) {
+               gd->major = sd_major((index & 0xf0) >> 4);
+               gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00);
+               gd->minors = SD_MINORS;
        }
-
+       gd->fops = &sd_fops;
        gd->private_data = &sdkp->driver;
        gd->queue = sdkp->device->request_queue;
 
@@ -1869,7 +1903,7 @@ static int sd_probe(struct device *dev)
        blk_queue_prep_rq(sdp->request_queue, sd_prep_fn);
 
        gd->driverfs_dev = &sdp->sdev_gendev;
-       gd->flags = GENHD_FL_DRIVERFS;
+       gd->flags = GENHD_FL_EXT_DEVT | GENHD_FL_DRIVERFS;
        if (sdp->removable)
                gd->flags |= GENHD_FL_REMOVABLE;
 
index 661f9f21650a57f6361650ec5b685bb01d595da9..ba9b9bbd4e7385e8d83f3ed4f4a1151b96ab3a1f 100644 (file)
@@ -47,7 +47,6 @@ static int sg_version_num = 30534;    /* 2 digits for each component */
 #include <linux/seq_file.h>
 #include <linux/blkdev.h>
 #include <linux/delay.h>
-#include <linux/scatterlist.h>
 #include <linux/blktrace_api.h>
 #include <linux/smp_lock.h>
 
@@ -69,7 +68,6 @@ static void sg_proc_cleanup(void);
 #endif
 
 #define SG_ALLOW_DIO_DEF 0
-#define SG_ALLOW_DIO_CODE /* compile out by commenting this define */
 
 #define SG_MAX_DEVS 32768
 
@@ -118,8 +116,8 @@ typedef struct sg_scatter_hold { /* holding area for scsi scatter gather info */
        unsigned short k_use_sg; /* Count of kernel scatter-gather pieces */
        unsigned sglist_len; /* size of malloc'd scatter-gather list ++ */
        unsigned bufflen;       /* Size of (aggregate) data buffer */
-       unsigned b_malloc_len;  /* actual len malloc'ed in buffer */
-       struct scatterlist *buffer;/* scatter list */
+       struct page **pages;
+       int page_order;
        char dio_in_use;        /* 0->indirect IO (or mmap), 1->dio */
        unsigned char cmd_opcode; /* first byte of command */
 } Sg_scatter_hold;
@@ -137,6 +135,8 @@ typedef struct sg_request { /* SG_MAX_QUEUE requests outstanding per file */
        char orphan;            /* 1 -> drop on sight, 0 -> normal */
        char sg_io_owned;       /* 1 -> packet belongs to SG_IO */
        volatile char done;     /* 0->before bh, 1->before read, 2->read */
+       struct request *rq;
+       struct bio *bio;
 } Sg_request;
 
 typedef struct sg_fd {         /* holds the state of a file descriptor */
@@ -175,8 +175,8 @@ typedef struct sg_device { /* holds the state of each scsi generic device */
 
 static int sg_fasync(int fd, struct file *filp, int mode);
 /* tasklet or soft irq callback */
-static void sg_cmd_done(void *data, char *sense, int result, int resid);
-static int sg_start_req(Sg_request * srp);
+static void sg_rq_end_io(struct request *rq, int uptodate);
+static int sg_start_req(Sg_request *srp, unsigned char *cmd);
 static void sg_finish_rem_req(Sg_request * srp);
 static int sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size);
 static int sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp,
@@ -188,17 +188,11 @@ static ssize_t sg_new_write(Sg_fd *sfp, struct file *file,
                        int read_only, Sg_request **o_srp);
 static int sg_common_write(Sg_fd * sfp, Sg_request * srp,
                           unsigned char *cmnd, int timeout, int blocking);
-static int sg_u_iovec(sg_io_hdr_t * hp, int sg_num, int ind,
-                     int wr_xf, int *countp, unsigned char __user **up);
-static int sg_write_xfer(Sg_request * srp);
-static int sg_read_xfer(Sg_request * srp);
 static int sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer);
 static void sg_remove_scat(Sg_scatter_hold * schp);
 static void sg_build_reserve(Sg_fd * sfp, int req_size);
 static void sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size);
 static void sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp);
-static struct page *sg_page_malloc(int rqSz, int lowDma, int *retSzp);
-static void sg_page_free(struct page *page, int size);
 static Sg_fd *sg_add_sfp(Sg_device * sdp, int dev);
 static int sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp);
 static void __sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp);
@@ -206,7 +200,6 @@ static Sg_request *sg_get_rq_mark(Sg_fd * sfp, int pack_id);
 static Sg_request *sg_add_request(Sg_fd * sfp);
 static int sg_remove_request(Sg_fd * sfp, Sg_request * srp);
 static int sg_res_in_use(Sg_fd * sfp);
-static int sg_build_direct(Sg_request * srp, Sg_fd * sfp, int dxfer_len);
 static Sg_device *sg_get_dev(int dev);
 #ifdef CONFIG_SCSI_PROC_FS
 static int sg_last_dev(void);
@@ -529,8 +522,7 @@ sg_new_read(Sg_fd * sfp, char __user *buf, size_t count, Sg_request * srp)
                err = -EFAULT;
                goto err_out;
        }
-       err = sg_read_xfer(srp);
-      err_out:
+err_out:
        sg_finish_rem_req(srp);
        return (0 == err) ? count : err;
 }
@@ -612,7 +604,10 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
        else
                hp->dxfer_direction = (mxsize > 0) ? SG_DXFER_FROM_DEV : SG_DXFER_NONE;
        hp->dxfer_len = mxsize;
-       hp->dxferp = (char __user *)buf + cmd_size;
+       if (hp->dxfer_direction == SG_DXFER_TO_DEV)
+               hp->dxferp = (char __user *)buf + cmd_size;
+       else
+               hp->dxferp = NULL;
        hp->sbp = NULL;
        hp->timeout = old_hdr.reply_len;        /* structure abuse ... */
        hp->flags = input_size; /* structure abuse ... */
@@ -732,16 +727,12 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp,
        SCSI_LOG_TIMEOUT(4, printk("sg_common_write:  scsi opcode=0x%02x, cmd_size=%d\n",
                          (int) cmnd[0], (int) hp->cmd_len));
 
-       if ((k = sg_start_req(srp))) {
+       k = sg_start_req(srp, cmnd);
+       if (k) {
                SCSI_LOG_TIMEOUT(1, printk("sg_common_write: start_req err=%d\n", k));
                sg_finish_rem_req(srp);
                return k;       /* probably out of space --> ENOMEM */
        }
-       if ((k = sg_write_xfer(srp))) {
-               SCSI_LOG_TIMEOUT(1, printk("sg_common_write: write_xfer, bad address\n"));
-               sg_finish_rem_req(srp);
-               return k;
-       }
        if (sdp->detached) {
                sg_finish_rem_req(srp);
                return -ENODEV;
@@ -763,20 +754,11 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp,
                break;
        }
        hp->duration = jiffies_to_msecs(jiffies);
-/* Now send everything of to mid-level. The next time we hear about this
-   packet is when sg_cmd_done() is called (i.e. a callback). */
-       if (scsi_execute_async(sdp->device, cmnd, hp->cmd_len, data_dir, srp->data.buffer,
-                               hp->dxfer_len, srp->data.k_use_sg, timeout,
-                               SG_DEFAULT_RETRIES, srp, sg_cmd_done,
-                               GFP_ATOMIC)) {
-               SCSI_LOG_TIMEOUT(1, printk("sg_common_write: scsi_execute_async failed\n"));
-               /*
-                * most likely out of mem, but could also be a bad map
-                */
-               sg_finish_rem_req(srp);
-               return -ENOMEM;
-       } else
-               return 0;
+
+       srp->rq->timeout = timeout;
+       blk_execute_rq_nowait(sdp->device->request_queue, sdp->disk,
+                             srp->rq, 1, sg_rq_end_io);
+       return 0;
 }
 
 static int
@@ -1192,8 +1174,7 @@ sg_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
        Sg_fd *sfp;
        unsigned long offset, len, sa;
        Sg_scatter_hold *rsv_schp;
-       struct scatterlist *sg;
-       int k;
+       int k, length;
 
        if ((NULL == vma) || (!(sfp = (Sg_fd *) vma->vm_private_data)))
                return VM_FAULT_SIGBUS;
@@ -1203,15 +1184,14 @@ sg_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
                return VM_FAULT_SIGBUS;
        SCSI_LOG_TIMEOUT(3, printk("sg_vma_fault: offset=%lu, scatg=%d\n",
                                   offset, rsv_schp->k_use_sg));
-       sg = rsv_schp->buffer;
        sa = vma->vm_start;
-       for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end);
-            ++k, sg = sg_next(sg)) {
+       length = 1 << (PAGE_SHIFT + rsv_schp->page_order);
+       for (k = 0; k < rsv_schp->k_use_sg && sa < vma->vm_end; k++) {
                len = vma->vm_end - sa;
-               len = (len < sg->length) ? len : sg->length;
+               len = (len < length) ? len : length;
                if (offset < len) {
-                       struct page *page;
-                       page = virt_to_page(page_address(sg_page(sg)) + offset);
+                       struct page *page = nth_page(rsv_schp->pages[k],
+                                                    offset >> PAGE_SHIFT);
                        get_page(page); /* increment page count */
                        vmf->page = page;
                        return 0; /* success */
@@ -1233,8 +1213,7 @@ sg_mmap(struct file *filp, struct vm_area_struct *vma)
        Sg_fd *sfp;
        unsigned long req_sz, len, sa;
        Sg_scatter_hold *rsv_schp;
-       int k;
-       struct scatterlist *sg;
+       int k, length;
 
        if ((!filp) || (!vma) || (!(sfp = (Sg_fd *) filp->private_data)))
                return -ENXIO;
@@ -1248,11 +1227,10 @@ sg_mmap(struct file *filp, struct vm_area_struct *vma)
                return -ENOMEM; /* cannot map more than reserved buffer */
 
        sa = vma->vm_start;
-       sg = rsv_schp->buffer;
-       for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end);
-            ++k, sg = sg_next(sg)) {
+       length = 1 << (PAGE_SHIFT + rsv_schp->page_order);
+       for (k = 0; k < rsv_schp->k_use_sg && sa < vma->vm_end; k++) {
                len = vma->vm_end - sa;
-               len = (len < sg->length) ? len : sg->length;
+               len = (len < length) ? len : length;
                sa += len;
        }
 
@@ -1263,16 +1241,19 @@ sg_mmap(struct file *filp, struct vm_area_struct *vma)
        return 0;
 }
 
-/* This function is a "bottom half" handler that is called by the
- * mid level when a command is completed (or has failed). */
-static void
-sg_cmd_done(void *data, char *sense, int result, int resid)
+/*
+ * This function is a "bottom half" handler that is called by the mid
+ * level when a command is completed (or has failed).
+ */
+static void sg_rq_end_io(struct request *rq, int uptodate)
 {
-       Sg_request *srp = data;
+       struct sg_request *srp = rq->end_io_data;
        Sg_device *sdp = NULL;
        Sg_fd *sfp;
        unsigned long iflags;
        unsigned int ms;
+       char *sense;
+       int result, resid;
 
        if (NULL == srp) {
                printk(KERN_ERR "sg_cmd_done: NULL request\n");
@@ -1286,6 +1267,9 @@ sg_cmd_done(void *data, char *sense, int result, int resid)
                return;
        }
 
+       sense = rq->sense;
+       result = rq->errors;
+       resid = rq->data_len;
 
        SCSI_LOG_TIMEOUT(4, printk("sg_cmd_done: %s, pack_id=%d, res=0x%x\n",
                sdp->disk->disk_name, srp->header.pack_id, result));
@@ -1296,7 +1280,6 @@ sg_cmd_done(void *data, char *sense, int result, int resid)
        if (0 != result) {
                struct scsi_sense_hdr sshdr;
 
-               memcpy(srp->sense_b, sense, sizeof (srp->sense_b));
                srp->header.status = 0xff & result;
                srp->header.masked_status = status_byte(result);
                srp->header.msg_status = msg_byte(result);
@@ -1634,37 +1617,79 @@ exit_sg(void)
        idr_destroy(&sg_index_idr);
 }
 
-static int
-sg_start_req(Sg_request * srp)
+static int sg_start_req(Sg_request *srp, unsigned char *cmd)
 {
        int res;
+       struct request *rq;
        Sg_fd *sfp = srp->parentfp;
        sg_io_hdr_t *hp = &srp->header;
        int dxfer_len = (int) hp->dxfer_len;
        int dxfer_dir = hp->dxfer_direction;
+       unsigned int iov_count = hp->iovec_count;
        Sg_scatter_hold *req_schp = &srp->data;
        Sg_scatter_hold *rsv_schp = &sfp->reserve;
+       struct request_queue *q = sfp->parentdp->device->request_queue;
+       struct rq_map_data *md, map_data;
+       int rw = hp->dxfer_direction == SG_DXFER_TO_DEV ? WRITE : READ;
+
+       SCSI_LOG_TIMEOUT(4, printk(KERN_INFO "sg_start_req: dxfer_len=%d\n",
+                                  dxfer_len));
+
+       rq = blk_get_request(q, rw, GFP_ATOMIC);
+       if (!rq)
+               return -ENOMEM;
+
+       memcpy(rq->cmd, cmd, hp->cmd_len);
+
+       rq->cmd_len = hp->cmd_len;
+       rq->cmd_type = REQ_TYPE_BLOCK_PC;
+
+       srp->rq = rq;
+       rq->end_io_data = srp;
+       rq->sense = srp->sense_b;
+       rq->retries = SG_DEFAULT_RETRIES;
 
-       SCSI_LOG_TIMEOUT(4, printk("sg_start_req: dxfer_len=%d\n", dxfer_len));
        if ((dxfer_len <= 0) || (dxfer_dir == SG_DXFER_NONE))
                return 0;
-       if (sg_allow_dio && (hp->flags & SG_FLAG_DIRECT_IO) &&
-           (dxfer_dir != SG_DXFER_UNKNOWN) && (0 == hp->iovec_count) &&
-           (!sfp->parentdp->device->host->unchecked_isa_dma)) {
-               res = sg_build_direct(srp, sfp, dxfer_len);
-               if (res <= 0)   /* -ve -> error, 0 -> done, 1 -> try indirect */
-                       return res;
-       }
-       if ((!sg_res_in_use(sfp)) && (dxfer_len <= rsv_schp->bufflen))
-               sg_link_reserve(sfp, srp, dxfer_len);
-       else {
-               res = sg_build_indirect(req_schp, sfp, dxfer_len);
-               if (res) {
-                       sg_remove_scat(req_schp);
-                       return res;
+
+       if (sg_allow_dio && hp->flags & SG_FLAG_DIRECT_IO &&
+           dxfer_dir != SG_DXFER_UNKNOWN && !iov_count &&
+           !sfp->parentdp->device->host->unchecked_isa_dma &&
+           blk_rq_aligned(q, hp->dxferp, dxfer_len))
+               md = NULL;
+       else
+               md = &map_data;
+
+       if (md) {
+               if (!sg_res_in_use(sfp) && dxfer_len <= rsv_schp->bufflen)
+                       sg_link_reserve(sfp, srp, dxfer_len);
+               else {
+                       res = sg_build_indirect(req_schp, sfp, dxfer_len);
+                       if (res)
+                               return res;
                }
+
+               md->pages = req_schp->pages;
+               md->page_order = req_schp->page_order;
+               md->nr_entries = req_schp->k_use_sg;
        }
-       return 0;
+
+       if (iov_count)
+               res = blk_rq_map_user_iov(q, rq, md, hp->dxferp, iov_count,
+                                         hp->dxfer_len, GFP_ATOMIC);
+       else
+               res = blk_rq_map_user(q, rq, md, hp->dxferp,
+                                     hp->dxfer_len, GFP_ATOMIC);
+
+       if (!res) {
+               srp->bio = rq->bio;
+
+               if (!md) {
+                       req_schp->dio_in_use = 1;
+                       hp->info |= SG_INFO_DIRECT_IO;
+               }
+       }
+       return res;
 }
 
 static void
@@ -1678,186 +1703,37 @@ sg_finish_rem_req(Sg_request * srp)
                sg_unlink_reserve(sfp, srp);
        else
                sg_remove_scat(req_schp);
+
+       if (srp->rq) {
+               if (srp->bio)
+                       blk_rq_unmap_user(srp->bio);
+
+               blk_put_request(srp->rq);
+       }
+
        sg_remove_request(sfp, srp);
 }
 
 static int
 sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp, int tablesize)
 {
-       int sg_bufflen = tablesize * sizeof(struct scatterlist);
+       int sg_bufflen = tablesize * sizeof(struct page *);
        gfp_t gfp_flags = GFP_ATOMIC | __GFP_NOWARN;
 
-       /*
-        * TODO: test without low_dma, we should not need it since
-        * the block layer will bounce the buffer for us
-        *
-        * XXX(hch): we shouldn't need GFP_DMA for the actual S/G list.
-        */
-       if (sfp->low_dma)
-                gfp_flags |= GFP_DMA;
-       schp->buffer = kzalloc(sg_bufflen, gfp_flags);
-       if (!schp->buffer)
+       schp->pages = kzalloc(sg_bufflen, gfp_flags);
+       if (!schp->pages)
                return -ENOMEM;
-       sg_init_table(schp->buffer, tablesize);
        schp->sglist_len = sg_bufflen;
        return tablesize;       /* number of scat_gath elements allocated */
 }
 
-#ifdef SG_ALLOW_DIO_CODE
-/* vvvvvvvv  following code borrowed from st driver's direct IO vvvvvvvvv */
-       /* TODO: hopefully we can use the generic block layer code */
-
-/* Pin down user pages and put them into a scatter gather list. Returns <= 0 if
-   - mapping of all pages not successful
-   (i.e., either completely successful or fails)
-*/
-static int 
-st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages, 
-                 unsigned long uaddr, size_t count, int rw)
-{
-       unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
-       unsigned long start = uaddr >> PAGE_SHIFT;
-       const int nr_pages = end - start;
-       int res, i, j;
-       struct page **pages;
-
-       /* User attempted Overflow! */
-       if ((uaddr + count) < uaddr)
-               return -EINVAL;
-
-       /* Too big */
-        if (nr_pages > max_pages)
-               return -ENOMEM;
-
-       /* Hmm? */
-       if (count == 0)
-               return 0;
-
-       if ((pages = kmalloc(max_pages * sizeof(*pages), GFP_ATOMIC)) == NULL)
-               return -ENOMEM;
-
-        /* Try to fault in all of the necessary pages */
-       down_read(&current->mm->mmap_sem);
-        /* rw==READ means read from drive, write into memory area */
-       res = get_user_pages(
-               current,
-               current->mm,
-               uaddr,
-               nr_pages,
-               rw == READ,
-               0, /* don't force */
-               pages,
-               NULL);
-       up_read(&current->mm->mmap_sem);
-
-       /* Errors and no page mapped should return here */
-       if (res < nr_pages)
-               goto out_unmap;
-
-        for (i=0; i < nr_pages; i++) {
-                /* FIXME: flush superflous for rw==READ,
-                 * probably wrong function for rw==WRITE
-                 */
-               flush_dcache_page(pages[i]);
-               /* ?? Is locking needed? I don't think so */
-               /* if (!trylock_page(pages[i]))
-                  goto out_unlock; */
-        }
-
-       sg_set_page(sgl, pages[0], 0, uaddr & ~PAGE_MASK);
-       if (nr_pages > 1) {
-               sgl[0].length = PAGE_SIZE - sgl[0].offset;
-               count -= sgl[0].length;
-               for (i=1; i < nr_pages ; i++)
-                       sg_set_page(&sgl[i], pages[i], count < PAGE_SIZE ? count : PAGE_SIZE, 0);
-       }
-       else {
-               sgl[0].length = count;
-       }
-
-       kfree(pages);
-       return nr_pages;
-
- out_unmap:
-       if (res > 0) {
-               for (j=0; j < res; j++)
-                       page_cache_release(pages[j]);
-               res = 0;
-       }
-       kfree(pages);
-       return res;
-}
-
-
-/* And unmap them... */
-static int 
-st_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_pages,
-                   int dirtied)
-{
-       int i;
-
-       for (i=0; i < nr_pages; i++) {
-               struct page *page = sg_page(&sgl[i]);
-
-               if (dirtied)
-                       SetPageDirty(page);
-               /* unlock_page(page); */
-               /* FIXME: cache flush missing for rw==READ
-                * FIXME: call the correct reference counting function
-                */
-               page_cache_release(page);
-       }
-
-       return 0;
-}
-
-/* ^^^^^^^^  above code borrowed from st driver's direct IO ^^^^^^^^^ */
-#endif
-
-
-/* Returns: -ve -> error, 0 -> done, 1 -> try indirect */
-static int
-sg_build_direct(Sg_request * srp, Sg_fd * sfp, int dxfer_len)
-{
-#ifdef SG_ALLOW_DIO_CODE
-       sg_io_hdr_t *hp = &srp->header;
-       Sg_scatter_hold *schp = &srp->data;
-       int sg_tablesize = sfp->parentdp->sg_tablesize;
-       int mx_sc_elems, res;
-       struct scsi_device *sdev = sfp->parentdp->device;
-
-       if (((unsigned long)hp->dxferp &
-                       queue_dma_alignment(sdev->request_queue)) != 0)
-               return 1;
-
-       mx_sc_elems = sg_build_sgat(schp, sfp, sg_tablesize);
-        if (mx_sc_elems <= 0) {
-                return 1;
-        }
-       res = st_map_user_pages(schp->buffer, mx_sc_elems,
-                               (unsigned long)hp->dxferp, dxfer_len, 
-                               (SG_DXFER_TO_DEV == hp->dxfer_direction) ? 1 : 0);
-       if (res <= 0) {
-               sg_remove_scat(schp);
-               return 1;
-       }
-       schp->k_use_sg = res;
-       schp->dio_in_use = 1;
-       hp->info |= SG_INFO_DIRECT_IO;
-       return 0;
-#else
-       return 1;
-#endif
-}
-
 static int
 sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
 {
-       struct scatterlist *sg;
-       int ret_sz = 0, k, rem_sz, num, mx_sc_elems;
+       int ret_sz = 0, i, k, rem_sz, num, mx_sc_elems;
        int sg_tablesize = sfp->parentdp->sg_tablesize;
-       int blk_size = buff_size;
-       struct page *p = NULL;
+       int blk_size = buff_size, order;
+       gfp_t gfp_mask = GFP_ATOMIC | __GFP_COMP | __GFP_NOWARN;
 
        if (blk_size < 0)
                return -EFAULT;
@@ -1881,15 +1757,26 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
                } else
                        scatter_elem_sz_prev = num;
        }
-       for (k = 0, sg = schp->buffer, rem_sz = blk_size;
-            (rem_sz > 0) && (k < mx_sc_elems);
-            ++k, rem_sz -= ret_sz, sg = sg_next(sg)) {
-               
+
+       if (sfp->low_dma)
+               gfp_mask |= GFP_DMA;
+
+       if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
+               gfp_mask |= __GFP_ZERO;
+
+       order = get_order(num);
+retry:
+       ret_sz = 1 << (PAGE_SHIFT + order);
+
+       for (k = 0, rem_sz = blk_size; rem_sz > 0 && k < mx_sc_elems;
+            k++, rem_sz -= ret_sz) {
+
                num = (rem_sz > scatter_elem_sz_prev) ?
-                     scatter_elem_sz_prev : rem_sz;
-               p = sg_page_malloc(num, sfp->low_dma, &ret_sz);
-               if (!p)
-                       return -ENOMEM;
+                       scatter_elem_sz_prev : rem_sz;
+
+               schp->pages[k] = alloc_pages(gfp_mask, order);
+               if (!schp->pages[k])
+                       goto out;
 
                if (num == scatter_elem_sz_prev) {
                        if (unlikely(ret_sz > scatter_elem_sz_prev)) {
@@ -1897,12 +1784,12 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
                                scatter_elem_sz_prev = ret_sz;
                        }
                }
-               sg_set_page(sg, p, (ret_sz > num) ? num : ret_sz, 0);
 
                SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k=%d, num=%d, "
                                 "ret_sz=%d\n", k, num, ret_sz));
        }               /* end of for loop */
 
+       schp->page_order = order;
        schp->k_use_sg = k;
        SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k_use_sg=%d, "
                         "rem_sz=%d\n", k, rem_sz));
@@ -1910,223 +1797,42 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
        schp->bufflen = blk_size;
        if (rem_sz > 0) /* must have failed */
                return -ENOMEM;
-
        return 0;
-}
-
-static int
-sg_write_xfer(Sg_request * srp)
-{
-       sg_io_hdr_t *hp = &srp->header;
-       Sg_scatter_hold *schp = &srp->data;
-       struct scatterlist *sg = schp->buffer;
-       int num_xfer = 0;
-       int j, k, onum, usglen, ksglen, res;
-       int iovec_count = (int) hp->iovec_count;
-       int dxfer_dir = hp->dxfer_direction;
-       unsigned char *p;
-       unsigned char __user *up;
-       int new_interface = ('\0' == hp->interface_id) ? 0 : 1;
-
-       if ((SG_DXFER_UNKNOWN == dxfer_dir) || (SG_DXFER_TO_DEV == dxfer_dir) ||
-           (SG_DXFER_TO_FROM_DEV == dxfer_dir)) {
-               num_xfer = (int) (new_interface ? hp->dxfer_len : hp->flags);
-               if (schp->bufflen < num_xfer)
-                       num_xfer = schp->bufflen;
-       }
-       if ((num_xfer <= 0) || (schp->dio_in_use) ||
-           (new_interface
-            && ((SG_FLAG_NO_DXFER | SG_FLAG_MMAP_IO) & hp->flags)))
-               return 0;
-
-       SCSI_LOG_TIMEOUT(4, printk("sg_write_xfer: num_xfer=%d, iovec_count=%d, k_use_sg=%d\n",
-                         num_xfer, iovec_count, schp->k_use_sg));
-       if (iovec_count) {
-               onum = iovec_count;
-               if (!access_ok(VERIFY_READ, hp->dxferp, SZ_SG_IOVEC * onum))
-                       return -EFAULT;
-       } else
-               onum = 1;
-
-       ksglen = sg->length;
-       p = page_address(sg_page(sg));
-       for (j = 0, k = 0; j < onum; ++j) {
-               res = sg_u_iovec(hp, iovec_count, j, 1, &usglen, &up);
-               if (res)
-                       return res;
-
-               for (; p; sg = sg_next(sg), ksglen = sg->length,
-                    p = page_address(sg_page(sg))) {
-                       if (usglen <= 0)
-                               break;
-                       if (ksglen > usglen) {
-                               if (usglen >= num_xfer) {
-                                       if (__copy_from_user(p, up, num_xfer))
-                                               return -EFAULT;
-                                       return 0;
-                               }
-                               if (__copy_from_user(p, up, usglen))
-                                       return -EFAULT;
-                               p += usglen;
-                               ksglen -= usglen;
-                               break;
-                       } else {
-                               if (ksglen >= num_xfer) {
-                                       if (__copy_from_user(p, up, num_xfer))
-                                               return -EFAULT;
-                                       return 0;
-                               }
-                               if (__copy_from_user(p, up, ksglen))
-                                       return -EFAULT;
-                               up += ksglen;
-                               usglen -= ksglen;
-                       }
-                       ++k;
-                       if (k >= schp->k_use_sg)
-                               return 0;
-               }
-       }
-
-       return 0;
-}
+out:
+       for (i = 0; i < k; i++)
+               __free_pages(schp->pages[k], order);
 
-static int
-sg_u_iovec(sg_io_hdr_t * hp, int sg_num, int ind,
-          int wr_xf, int *countp, unsigned char __user **up)
-{
-       int num_xfer = (int) hp->dxfer_len;
-       unsigned char __user *p = hp->dxferp;
-       int count;
+       if (--order >= 0)
+               goto retry;
 
-       if (0 == sg_num) {
-               if (wr_xf && ('\0' == hp->interface_id))
-                       count = (int) hp->flags;        /* holds "old" input_size */
-               else
-                       count = num_xfer;
-       } else {
-               sg_iovec_t iovec;
-               if (__copy_from_user(&iovec, p + ind*SZ_SG_IOVEC, SZ_SG_IOVEC))
-                       return -EFAULT;
-               p = iovec.iov_base;
-               count = (int) iovec.iov_len;
-       }
-       if (!access_ok(wr_xf ? VERIFY_READ : VERIFY_WRITE, p, count))
-               return -EFAULT;
-       if (up)
-               *up = p;
-       if (countp)
-               *countp = count;
-       return 0;
+       return -ENOMEM;
 }
 
 static void
 sg_remove_scat(Sg_scatter_hold * schp)
 {
        SCSI_LOG_TIMEOUT(4, printk("sg_remove_scat: k_use_sg=%d\n", schp->k_use_sg));
-       if (schp->buffer && (schp->sglist_len > 0)) {
-               struct scatterlist *sg = schp->buffer;
-
-               if (schp->dio_in_use) {
-#ifdef SG_ALLOW_DIO_CODE
-                       st_unmap_user_pages(sg, schp->k_use_sg, TRUE);
-#endif
-               } else {
+       if (schp->pages && schp->sglist_len > 0) {
+               if (!schp->dio_in_use) {
                        int k;
 
-                       for (k = 0; (k < schp->k_use_sg) && sg_page(sg);
-                            ++k, sg = sg_next(sg)) {
+                       for (k = 0; k < schp->k_use_sg && schp->pages[k]; k++) {
                                SCSI_LOG_TIMEOUT(5, printk(
-                                   "sg_remove_scat: k=%d, pg=0x%p, len=%d\n",
-                                   k, sg_page(sg), sg->length));
-                               sg_page_free(sg_page(sg), sg->length);
+                                   "sg_remove_scat: k=%d, pg=0x%p\n",
+                                   k, schp->pages[k]));
+                               __free_pages(schp->pages[k], schp->page_order);
                        }
-               }
-               kfree(schp->buffer);
-       }
-       memset(schp, 0, sizeof (*schp));
-}
 
-static int
-sg_read_xfer(Sg_request * srp)
-{
-       sg_io_hdr_t *hp = &srp->header;
-       Sg_scatter_hold *schp = &srp->data;
-       struct scatterlist *sg = schp->buffer;
-       int num_xfer = 0;
-       int j, k, onum, usglen, ksglen, res;
-       int iovec_count = (int) hp->iovec_count;
-       int dxfer_dir = hp->dxfer_direction;
-       unsigned char *p;
-       unsigned char __user *up;
-       int new_interface = ('\0' == hp->interface_id) ? 0 : 1;
-
-       if ((SG_DXFER_UNKNOWN == dxfer_dir) || (SG_DXFER_FROM_DEV == dxfer_dir)
-           || (SG_DXFER_TO_FROM_DEV == dxfer_dir)) {
-               num_xfer = hp->dxfer_len;
-               if (schp->bufflen < num_xfer)
-                       num_xfer = schp->bufflen;
-       }
-       if ((num_xfer <= 0) || (schp->dio_in_use) ||
-           (new_interface
-            && ((SG_FLAG_NO_DXFER | SG_FLAG_MMAP_IO) & hp->flags)))
-               return 0;
-
-       SCSI_LOG_TIMEOUT(4, printk("sg_read_xfer: num_xfer=%d, iovec_count=%d, k_use_sg=%d\n",
-                         num_xfer, iovec_count, schp->k_use_sg));
-       if (iovec_count) {
-               onum = iovec_count;
-               if (!access_ok(VERIFY_READ, hp->dxferp, SZ_SG_IOVEC * onum))
-                       return -EFAULT;
-       } else
-               onum = 1;
-
-       p = page_address(sg_page(sg));
-       ksglen = sg->length;
-       for (j = 0, k = 0; j < onum; ++j) {
-               res = sg_u_iovec(hp, iovec_count, j, 0, &usglen, &up);
-               if (res)
-                       return res;
-
-               for (; p; sg = sg_next(sg), ksglen = sg->length,
-                    p = page_address(sg_page(sg))) {
-                       if (usglen <= 0)
-                               break;
-                       if (ksglen > usglen) {
-                               if (usglen >= num_xfer) {
-                                       if (__copy_to_user(up, p, num_xfer))
-                                               return -EFAULT;
-                                       return 0;
-                               }
-                               if (__copy_to_user(up, p, usglen))
-                                       return -EFAULT;
-                               p += usglen;
-                               ksglen -= usglen;
-                               break;
-                       } else {
-                               if (ksglen >= num_xfer) {
-                                       if (__copy_to_user(up, p, num_xfer))
-                                               return -EFAULT;
-                                       return 0;
-                               }
-                               if (__copy_to_user(up, p, ksglen))
-                                       return -EFAULT;
-                               up += ksglen;
-                               usglen -= ksglen;
-                       }
-                       ++k;
-                       if (k >= schp->k_use_sg)
-                               return 0;
+                       kfree(schp->pages);
                }
        }
-
-       return 0;
+       memset(schp, 0, sizeof (*schp));
 }
 
 static int
 sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer)
 {
        Sg_scatter_hold *schp = &srp->data;
-       struct scatterlist *sg = schp->buffer;
        int k, num;
 
        SCSI_LOG_TIMEOUT(4, printk("sg_read_oxfer: num_read_xfer=%d\n",
@@ -2134,15 +1840,15 @@ sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer)
        if ((!outp) || (num_read_xfer <= 0))
                return 0;
 
-       for (k = 0; (k < schp->k_use_sg) && sg_page(sg); ++k, sg = sg_next(sg)) {
-               num = sg->length;
+       num = 1 << (PAGE_SHIFT + schp->page_order);
+       for (k = 0; k < schp->k_use_sg && schp->pages[k]; k++) {
                if (num > num_read_xfer) {
-                       if (__copy_to_user(outp, page_address(sg_page(sg)),
+                       if (__copy_to_user(outp, page_address(schp->pages[k]),
                                           num_read_xfer))
                                return -EFAULT;
                        break;
                } else {
-                       if (__copy_to_user(outp, page_address(sg_page(sg)),
+                       if (__copy_to_user(outp, page_address(schp->pages[k]),
                                           num))
                                return -EFAULT;
                        num_read_xfer -= num;
@@ -2177,24 +1883,21 @@ sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size)
 {
        Sg_scatter_hold *req_schp = &srp->data;
        Sg_scatter_hold *rsv_schp = &sfp->reserve;
-       struct scatterlist *sg = rsv_schp->buffer;
        int k, num, rem;
 
        srp->res_used = 1;
        SCSI_LOG_TIMEOUT(4, printk("sg_link_reserve: size=%d\n", size));
        rem = size;
 
-       for (k = 0; k < rsv_schp->k_use_sg; ++k, sg = sg_next(sg)) {
-               num = sg->length;
+       num = 1 << (PAGE_SHIFT + rsv_schp->page_order);
+       for (k = 0; k < rsv_schp->k_use_sg; k++) {
                if (rem <= num) {
-                       sfp->save_scat_len = num;
-                       sg->length = rem;
                        req_schp->k_use_sg = k + 1;
                        req_schp->sglist_len = rsv_schp->sglist_len;
-                       req_schp->buffer = rsv_schp->buffer;
+                       req_schp->pages = rsv_schp->pages;
 
                        req_schp->bufflen = size;
-                       req_schp->b_malloc_len = rsv_schp->b_malloc_len;
+                       req_schp->page_order = rsv_schp->page_order;
                        break;
                } else
                        rem -= num;
@@ -2208,22 +1911,13 @@ static void
 sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp)
 {
        Sg_scatter_hold *req_schp = &srp->data;
-       Sg_scatter_hold *rsv_schp = &sfp->reserve;
 
        SCSI_LOG_TIMEOUT(4, printk("sg_unlink_reserve: req->k_use_sg=%d\n",
                                   (int) req_schp->k_use_sg));
-       if ((rsv_schp->k_use_sg > 0) && (req_schp->k_use_sg > 0)) {
-               struct scatterlist *sg = rsv_schp->buffer;
-
-               if (sfp->save_scat_len > 0)
-                       (sg + (req_schp->k_use_sg - 1))->length =
-                           (unsigned) sfp->save_scat_len;
-               else
-                       SCSI_LOG_TIMEOUT(1, printk ("sg_unlink_reserve: BAD save_scat_len\n"));
-       }
        req_schp->k_use_sg = 0;
        req_schp->bufflen = 0;
-       req_schp->buffer = NULL;
+       req_schp->pages = NULL;
+       req_schp->page_order = 0;
        req_schp->sglist_len = 0;
        sfp->save_scat_len = 0;
        srp->res_used = 0;
@@ -2481,53 +2175,6 @@ sg_res_in_use(Sg_fd * sfp)
        return srp ? 1 : 0;
 }
 
-/* The size fetched (value output via retSzp) set when non-NULL return */
-static struct page *
-sg_page_malloc(int rqSz, int lowDma, int *retSzp)
-{
-       struct page *resp = NULL;
-       gfp_t page_mask;
-       int order, a_size;
-       int resSz;
-
-       if ((rqSz <= 0) || (NULL == retSzp))
-               return resp;
-
-       if (lowDma)
-               page_mask = GFP_ATOMIC | GFP_DMA | __GFP_COMP | __GFP_NOWARN;
-       else
-               page_mask = GFP_ATOMIC | __GFP_COMP | __GFP_NOWARN;
-
-       for (order = 0, a_size = PAGE_SIZE; a_size < rqSz;
-            order++, a_size <<= 1) ;
-       resSz = a_size;         /* rounded up if necessary */
-       resp = alloc_pages(page_mask, order);
-       while ((!resp) && order) {
-               --order;
-               a_size >>= 1;   /* divide by 2, until PAGE_SIZE */
-               resp =  alloc_pages(page_mask, order);  /* try half */
-               resSz = a_size;
-       }
-       if (resp) {
-               if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
-                       memset(page_address(resp), 0, resSz);
-               *retSzp = resSz;
-       }
-       return resp;
-}
-
-static void
-sg_page_free(struct page *page, int size)
-{
-       int order, a_size;
-
-       if (!page)
-               return;
-       for (order = 0, a_size = PAGE_SIZE; a_size < size;
-            order++, a_size <<= 1) ;
-       __free_pages(page, order);
-}
-
 #ifdef CONFIG_SCSI_PROC_FS
 static int
 sg_idr_max_id(int id, void *p, void *data)
index 27f5bfd1def343e205c2710a587571650026410f..0f17009c99d2f75581ea96b30e3927f89beaa408 100644 (file)
@@ -331,7 +331,7 @@ static int sr_done(struct scsi_cmnd *SCpnt)
 
 static int sr_prep_fn(struct request_queue *q, struct request *rq)
 {
-       int block=0, this_count, s_size, timeout = SR_TIMEOUT;
+       int block = 0, this_count, s_size;
        struct scsi_cd *cd;
        struct scsi_cmnd *SCpnt;
        struct scsi_device *sdp = q->queuedata;
@@ -461,7 +461,6 @@ static int sr_prep_fn(struct request_queue *q, struct request *rq)
        SCpnt->transfersize = cd->device->sector_size;
        SCpnt->underflow = this_count << 9;
        SCpnt->allowed = MAX_RETRIES;
-       SCpnt->timeout_per_command = timeout;
 
        /*
         * This indicates that the command is ready from our end to be
@@ -620,6 +619,8 @@ static int sr_probe(struct device *dev)
        disk->fops = &sr_bdops;
        disk->flags = GENHD_FL_CD;
 
+       blk_queue_rq_timeout(sdev->request_queue, SR_TIMEOUT);
+
        cd->device = sdev;
        cd->disk = disk;
        cd->driver = &sr_template;
@@ -878,7 +879,7 @@ static void sr_kref_release(struct kref *kref)
        struct gendisk *disk = cd->disk;
 
        spin_lock(&sr_index_lock);
-       clear_bit(disk->first_minor, sr_index_bits);
+       clear_bit(MINOR(disk_devt(disk)), sr_index_bits);
        spin_unlock(&sr_index_lock);
 
        unregister_cdrom(&cd->cdi);
index d39107b7669bfb22e3fa1e278166dd2c2766616f..f4e6cde1fd0d5ed132723e57bfabac9c261f54cd 100644 (file)
@@ -519,8 +519,8 @@ static int sym53c8xx_queue_command(struct scsi_cmnd *cmd,
         *  Shorten our settle_time if needed for 
         *  this command not to time out.
         */
-       if (np->s.settle_time_valid && cmd->timeout_per_command) {
-               unsigned long tlimit = jiffies + cmd->timeout_per_command;
+       if (np->s.settle_time_valid && cmd->request->timeout) {
+               unsigned long tlimit = jiffies + cmd->request->timeout;
                tlimit -= SYM_CONF_TIMER_INTERVAL*2;
                if (time_after(np->s.settle_time, tlimit)) {
                        np->s.settle_time = tlimit;
index 1723d71cbf3fa383ed99e706721027e918fa80da..69ac6e590f1d1db0d1a85b0769046220f09dda7a 100644 (file)
@@ -2573,8 +2573,8 @@ static struct pci_driver dc390_driver = {
 static int __init dc390_module_init(void)
 {
        if (!disable_clustering)
-               printk(KERN_INFO "DC390: clustering now enabled by default. If you get problems load\n"
-                      "\twith \"disable_clustering=1\" and report to maintainers\n");
+               printk(KERN_INFO "DC390: clustering now enabled by default. If you get problems load\n");
+               printk(KERN_INFO "       with \"disable_clustering=1\" and report to maintainers\n");
 
        if (tmscsim[0] == -1 || tmscsim[0] > 15) {
                tmscsim[0] = 7;
index c3e174b35fe6a179baac8ef098b465f0ab51f515..19caf7c962ace6c58868ed4fd2196212faf755ef 100644 (file)
@@ -107,7 +107,8 @@ void bio_integrity_free(struct bio *bio, struct bio_set *bs)
        BUG_ON(bip == NULL);
 
        /* A cloned bio doesn't own the integrity metadata */
-       if (!bio_flagged(bio, BIO_CLONED) && bip->bip_buf != NULL)
+       if (!bio_flagged(bio, BIO_CLONED) && !bio_flagged(bio, BIO_FS_INTEGRITY)
+           && bip->bip_buf != NULL)
                kfree(bip->bip_buf);
 
        mempool_free(bip->bip_vec, bs->bvec_pools[bip->bip_pool]);
@@ -150,6 +151,24 @@ int bio_integrity_add_page(struct bio *bio, struct page *page,
 }
 EXPORT_SYMBOL(bio_integrity_add_page);
 
+static int bdev_integrity_enabled(struct block_device *bdev, int rw)
+{
+       struct blk_integrity *bi = bdev_get_integrity(bdev);
+
+       if (bi == NULL)
+               return 0;
+
+       if (rw == READ && bi->verify_fn != NULL &&
+           (bi->flags & INTEGRITY_FLAG_READ))
+               return 1;
+
+       if (rw == WRITE && bi->generate_fn != NULL &&
+           (bi->flags & INTEGRITY_FLAG_WRITE))
+               return 1;
+
+       return 0;
+}
+
 /**
  * bio_integrity_enabled - Check whether integrity can be passed
  * @bio:       bio to check
@@ -313,6 +332,14 @@ static void bio_integrity_generate(struct bio *bio)
        }
 }
 
+static inline unsigned short blk_integrity_tuple_size(struct blk_integrity *bi)
+{
+       if (bi)
+               return bi->tuple_size;
+
+       return 0;
+}
+
 /**
  * bio_integrity_prep - Prepare bio for integrity I/O
  * @bio:       bio to prepare
index 3cba7ae34d758c860ecff09f2be059663d2de35b..77a55bcceedbc6afc79f7a081c0f0af5e7c4f46e 100644 (file)
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -30,7 +30,7 @@
 
 static struct kmem_cache *bio_slab __read_mostly;
 
-mempool_t *bio_split_pool __read_mostly;
+static mempool_t *bio_split_pool __read_mostly;
 
 /*
  * if you change this list, also change bvec_alloc or things will
@@ -60,25 +60,46 @@ struct bio_vec *bvec_alloc_bs(gfp_t gfp_mask, int nr, unsigned long *idx, struct
        struct bio_vec *bvl;
 
        /*
-        * see comment near bvec_array define!
+        * If 'bs' is given, lookup the pool and do the mempool alloc.
+        * If not, this is a bio_kmalloc() allocation and just do a
+        * kzalloc() for the exact number of vecs right away.
         */
-       switch (nr) {
-               case   1        : *idx = 0; break;
-               case   2 ...   4: *idx = 1; break;
-               case   5 ...  16: *idx = 2; break;
-               case  17 ...  64: *idx = 3; break;
-               case  65 ... 128: *idx = 4; break;
-               case 129 ... BIO_MAX_PAGES: *idx = 5; break;
+       if (bs) {
+               /*
+                * see comment near bvec_array define!
+                */
+               switch (nr) {
+               case 1:
+                       *idx = 0;
+                       break;
+               case 2 ... 4:
+                       *idx = 1;
+                       break;
+               case 5 ... 16:
+                       *idx = 2;
+                       break;
+               case 17 ... 64:
+                       *idx = 3;
+                       break;
+               case 65 ... 128:
+                       *idx = 4;
+                       break;
+               case 129 ... BIO_MAX_PAGES:
+                       *idx = 5;
+                       break;
                default:
                        return NULL;
-       }
-       /*
-        * idx now points to the pool we want to allocate from
-        */
+               }
 
-       bvl = mempool_alloc(bs->bvec_pools[*idx], gfp_mask);
-       if (bvl)
-               memset(bvl, 0, bvec_nr_vecs(*idx) * sizeof(struct bio_vec));
+               /*
+                * idx now points to the pool we want to allocate from
+                */
+               bvl = mempool_alloc(bs->bvec_pools[*idx], gfp_mask);
+               if (bvl)
+                       memset(bvl, 0,
+                               bvec_nr_vecs(*idx) * sizeof(struct bio_vec));
+       } else
+               bvl = kzalloc(nr * sizeof(struct bio_vec), gfp_mask);
 
        return bvl;
 }
@@ -107,10 +128,17 @@ static void bio_fs_destructor(struct bio *bio)
        bio_free(bio, fs_bio_set);
 }
 
+static void bio_kmalloc_destructor(struct bio *bio)
+{
+       kfree(bio->bi_io_vec);
+       kfree(bio);
+}
+
 void bio_init(struct bio *bio)
 {
        memset(bio, 0, sizeof(*bio));
        bio->bi_flags = 1 << BIO_UPTODATE;
+       bio->bi_comp_cpu = -1;
        atomic_set(&bio->bi_cnt, 1);
 }
 
@@ -118,19 +146,25 @@ void bio_init(struct bio *bio)
  * bio_alloc_bioset - allocate a bio for I/O
  * @gfp_mask:   the GFP_ mask given to the slab allocator
  * @nr_iovecs: number of iovecs to pre-allocate
- * @bs:                the bio_set to allocate from
+ * @bs:                the bio_set to allocate from. If %NULL, just use kmalloc
  *
  * Description:
- *   bio_alloc_bioset will first try it's on mempool to satisfy the allocation.
+ *   bio_alloc_bioset will first try its own mempool to satisfy the allocation.
  *   If %__GFP_WAIT is set then we will block on the internal pool waiting
- *   for a &struct bio to become free.
+ *   for a &struct bio to become free. If a %NULL @bs is passed in, we will
+ *   fall back to just using @kmalloc to allocate the required memory.
  *
  *   allocate bio and iovecs from the memory pools specified by the
- *   bio_set structure.
+ *   bio_set structure, or @kmalloc if none given.
  **/
 struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs)
 {
-       struct bio *bio = mempool_alloc(bs->bio_pool, gfp_mask);
+       struct bio *bio;
+
+       if (bs)
+               bio = mempool_alloc(bs->bio_pool, gfp_mask);
+       else
+               bio = kmalloc(sizeof(*bio), gfp_mask);
 
        if (likely(bio)) {
                struct bio_vec *bvl = NULL;
@@ -141,7 +175,10 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs)
 
                        bvl = bvec_alloc_bs(gfp_mask, nr_iovecs, &idx, bs);
                        if (unlikely(!bvl)) {
-                               mempool_free(bio, bs->bio_pool);
+                               if (bs)
+                                       mempool_free(bio, bs->bio_pool);
+                               else
+                                       kfree(bio);
                                bio = NULL;
                                goto out;
                        }
@@ -164,6 +201,23 @@ struct bio *bio_alloc(gfp_t gfp_mask, int nr_iovecs)
        return bio;
 }
 
+/*
+ * Like bio_alloc(), but doesn't use a mempool backing. This means that
+ * it CAN fail, but while bio_alloc() can only be used for allocations
+ * that have a short (finite) life span, bio_kmalloc() should be used
+ * for more permanent bio allocations (like allocating some bio's for
+ * initalization or setup purposes).
+ */
+struct bio *bio_kmalloc(gfp_t gfp_mask, int nr_iovecs)
+{
+       struct bio *bio = bio_alloc_bioset(gfp_mask, nr_iovecs, NULL);
+
+       if (bio)
+               bio->bi_destructor = bio_kmalloc_destructor;
+
+       return bio;
+}
+
 void zero_fill_bio(struct bio *bio)
 {
        unsigned long flags;
@@ -208,14 +262,6 @@ inline int bio_phys_segments(struct request_queue *q, struct bio *bio)
        return bio->bi_phys_segments;
 }
 
-inline int bio_hw_segments(struct request_queue *q, struct bio *bio)
-{
-       if (unlikely(!bio_flagged(bio, BIO_SEG_VALID)))
-               blk_recount_segments(q, bio);
-
-       return bio->bi_hw_segments;
-}
-
 /**
  *     __bio_clone     -       clone a bio
  *     @bio: destination bio
@@ -350,8 +396,7 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
         */
 
        while (bio->bi_phys_segments >= q->max_phys_segments
-              || bio->bi_hw_segments >= q->max_hw_segments
-              || BIOVEC_VIRT_OVERSIZE(bio->bi_size)) {
+              || bio->bi_phys_segments >= q->max_hw_segments) {
 
                if (retried_segments)
                        return 0;
@@ -395,13 +440,11 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
        }
 
        /* If we may be able to merge these biovecs, force a recount */
-       if (bio->bi_vcnt && (BIOVEC_PHYS_MERGEABLE(bvec-1, bvec) ||
-           BIOVEC_VIRT_MERGEABLE(bvec-1, bvec)))
+       if (bio->bi_vcnt && (BIOVEC_PHYS_MERGEABLE(bvec-1, bvec)))
                bio->bi_flags &= ~(1 << BIO_SEG_VALID);
 
        bio->bi_vcnt++;
        bio->bi_phys_segments++;
-       bio->bi_hw_segments++;
  done:
        bio->bi_size += len;
        return len;
@@ -449,16 +492,19 @@ int bio_add_page(struct bio *bio, struct page *page, unsigned int len,
 
 struct bio_map_data {
        struct bio_vec *iovecs;
-       int nr_sgvecs;
        struct sg_iovec *sgvecs;
+       int nr_sgvecs;
+       int is_our_pages;
 };
 
 static void bio_set_map_data(struct bio_map_data *bmd, struct bio *bio,
-                            struct sg_iovec *iov, int iov_count)
+                            struct sg_iovec *iov, int iov_count,
+                            int is_our_pages)
 {
        memcpy(bmd->iovecs, bio->bi_io_vec, sizeof(struct bio_vec) * bio->bi_vcnt);
        memcpy(bmd->sgvecs, iov, sizeof(struct sg_iovec) * iov_count);
        bmd->nr_sgvecs = iov_count;
+       bmd->is_our_pages = is_our_pages;
        bio->bi_private = bmd;
 }
 
@@ -493,7 +539,8 @@ static struct bio_map_data *bio_alloc_map_data(int nr_segs, int iov_count,
 }
 
 static int __bio_copy_iov(struct bio *bio, struct bio_vec *iovecs,
-                         struct sg_iovec *iov, int iov_count, int uncopy)
+                         struct sg_iovec *iov, int iov_count, int uncopy,
+                         int do_free_page)
 {
        int ret = 0, i;
        struct bio_vec *bvec;
@@ -536,7 +583,7 @@ static int __bio_copy_iov(struct bio *bio, struct bio_vec *iovecs,
                        }
                }
 
-               if (uncopy)
+               if (do_free_page)
                        __free_page(bvec->bv_page);
        }
 
@@ -553,10 +600,11 @@ static int __bio_copy_iov(struct bio *bio, struct bio_vec *iovecs,
 int bio_uncopy_user(struct bio *bio)
 {
        struct bio_map_data *bmd = bio->bi_private;
-       int ret;
-
-       ret = __bio_copy_iov(bio, bmd->iovecs, bmd->sgvecs, bmd->nr_sgvecs, 1);
+       int ret = 0;
 
+       if (!bio_flagged(bio, BIO_NULL_MAPPED))
+               ret = __bio_copy_iov(bio, bmd->iovecs, bmd->sgvecs,
+                                    bmd->nr_sgvecs, 1, bmd->is_our_pages);
        bio_free_map_data(bmd);
        bio_put(bio);
        return ret;
@@ -565,16 +613,20 @@ int bio_uncopy_user(struct bio *bio)
 /**
  *     bio_copy_user_iov       -       copy user data to bio
  *     @q: destination block queue
+ *     @map_data: pointer to the rq_map_data holding pages (if necessary)
  *     @iov:   the iovec.
  *     @iov_count: number of elements in the iovec
  *     @write_to_vm: bool indicating writing to pages or not
+ *     @gfp_mask: memory allocation flags
  *
  *     Prepares and returns a bio for indirect user io, bouncing data
  *     to/from kernel pages as necessary. Must be paired with
  *     call bio_uncopy_user() on io completion.
  */
-struct bio *bio_copy_user_iov(struct request_queue *q, struct sg_iovec *iov,
-                             int iov_count, int write_to_vm)
+struct bio *bio_copy_user_iov(struct request_queue *q,
+                             struct rq_map_data *map_data,
+                             struct sg_iovec *iov, int iov_count,
+                             int write_to_vm, gfp_t gfp_mask)
 {
        struct bio_map_data *bmd;
        struct bio_vec *bvec;
@@ -597,25 +649,38 @@ struct bio *bio_copy_user_iov(struct request_queue *q, struct sg_iovec *iov,
                len += iov[i].iov_len;
        }
 
-       bmd = bio_alloc_map_data(nr_pages, iov_count, GFP_KERNEL);
+       bmd = bio_alloc_map_data(nr_pages, iov_count, gfp_mask);
        if (!bmd)
                return ERR_PTR(-ENOMEM);
 
        ret = -ENOMEM;
-       bio = bio_alloc(GFP_KERNEL, nr_pages);
+       bio = bio_alloc(gfp_mask, nr_pages);
        if (!bio)
                goto out_bmd;
 
        bio->bi_rw |= (!write_to_vm << BIO_RW);
 
        ret = 0;
+       i = 0;
        while (len) {
-               unsigned int bytes = PAGE_SIZE;
+               unsigned int bytes;
+
+               if (map_data)
+                       bytes = 1U << (PAGE_SHIFT + map_data->page_order);
+               else
+                       bytes = PAGE_SIZE;
 
                if (bytes > len)
                        bytes = len;
 
-               page = alloc_page(q->bounce_gfp | GFP_KERNEL);
+               if (map_data) {
+                       if (i == map_data->nr_entries) {
+                               ret = -ENOMEM;
+                               break;
+                       }
+                       page = map_data->pages[i++];
+               } else
+                       page = alloc_page(q->bounce_gfp | gfp_mask);
                if (!page) {
                        ret = -ENOMEM;
                        break;
@@ -634,16 +699,17 @@ struct bio *bio_copy_user_iov(struct request_queue *q, struct sg_iovec *iov,
         * success
         */
        if (!write_to_vm) {
-               ret = __bio_copy_iov(bio, bio->bi_io_vec, iov, iov_count, 0);
+               ret = __bio_copy_iov(bio, bio->bi_io_vec, iov, iov_count, 0, 0);
                if (ret)
                        goto cleanup;
        }
 
-       bio_set_map_data(bmd, bio, iov, iov_count);
+       bio_set_map_data(bmd, bio, iov, iov_count, map_data ? 0 : 1);
        return bio;
 cleanup:
-       bio_for_each_segment(bvec, bio, i)
-               __free_page(bvec->bv_page);
+       if (!map_data)
+               bio_for_each_segment(bvec, bio, i)
+                       __free_page(bvec->bv_page);
 
        bio_put(bio);
 out_bmd:
@@ -654,29 +720,32 @@ out_bmd:
 /**
  *     bio_copy_user   -       copy user data to bio
  *     @q: destination block queue
+ *     @map_data: pointer to the rq_map_data holding pages (if necessary)
  *     @uaddr: start of user address
  *     @len: length in bytes
  *     @write_to_vm: bool indicating writing to pages or not
+ *     @gfp_mask: memory allocation flags
  *
  *     Prepares and returns a bio for indirect user io, bouncing data
  *     to/from kernel pages as necessary. Must be paired with
  *     call bio_uncopy_user() on io completion.
  */
-struct bio *bio_copy_user(struct request_queue *q, unsigned long uaddr,
-                         unsigned int len, int write_to_vm)
+struct bio *bio_copy_user(struct request_queue *q, struct rq_map_data *map_data,
+                         unsigned long uaddr, unsigned int len,
+                         int write_to_vm, gfp_t gfp_mask)
 {
        struct sg_iovec iov;
 
        iov.iov_base = (void __user *)uaddr;
        iov.iov_len = len;
 
-       return bio_copy_user_iov(q, &iov, 1, write_to_vm);
+       return bio_copy_user_iov(q, map_data, &iov, 1, write_to_vm, gfp_mask);
 }
 
 static struct bio *__bio_map_user_iov(struct request_queue *q,
                                      struct block_device *bdev,
                                      struct sg_iovec *iov, int iov_count,
-                                     int write_to_vm)
+                                     int write_to_vm, gfp_t gfp_mask)
 {
        int i, j;
        int nr_pages = 0;
@@ -702,12 +771,12 @@ static struct bio *__bio_map_user_iov(struct request_queue *q,
        if (!nr_pages)
                return ERR_PTR(-EINVAL);
 
-       bio = bio_alloc(GFP_KERNEL, nr_pages);
+       bio = bio_alloc(gfp_mask, nr_pages);
        if (!bio)
                return ERR_PTR(-ENOMEM);
 
        ret = -ENOMEM;
-       pages = kcalloc(nr_pages, sizeof(struct page *), GFP_KERNEL);
+       pages = kcalloc(nr_pages, sizeof(struct page *), gfp_mask);
        if (!pages)
                goto out;
 
@@ -786,19 +855,21 @@ static struct bio *__bio_map_user_iov(struct request_queue *q,
  *     @uaddr: start of user address
  *     @len: length in bytes
  *     @write_to_vm: bool indicating writing to pages or not
+ *     @gfp_mask: memory allocation flags
  *
  *     Map the user space address into a bio suitable for io to a block
  *     device. Returns an error pointer in case of error.
  */
 struct bio *bio_map_user(struct request_queue *q, struct block_device *bdev,
-                        unsigned long uaddr, unsigned int len, int write_to_vm)
+                        unsigned long uaddr, unsigned int len, int write_to_vm,
+                        gfp_t gfp_mask)
 {
        struct sg_iovec iov;
 
        iov.iov_base = (void __user *)uaddr;
        iov.iov_len = len;
 
-       return bio_map_user_iov(q, bdev, &iov, 1, write_to_vm);
+       return bio_map_user_iov(q, bdev, &iov, 1, write_to_vm, gfp_mask);
 }
 
 /**
@@ -808,18 +879,19 @@ struct bio *bio_map_user(struct request_queue *q, struct block_device *bdev,
  *     @iov:   the iovec.
  *     @iov_count: number of elements in the iovec
  *     @write_to_vm: bool indicating writing to pages or not
+ *     @gfp_mask: memory allocation flags
  *
  *     Map the user space address into a bio suitable for io to a block
  *     device. Returns an error pointer in case of error.
  */
 struct bio *bio_map_user_iov(struct request_queue *q, struct block_device *bdev,
                             struct sg_iovec *iov, int iov_count,
-                            int write_to_vm)
+                            int write_to_vm, gfp_t gfp_mask)
 {
        struct bio *bio;
 
-       bio = __bio_map_user_iov(q, bdev, iov, iov_count, write_to_vm);
-
+       bio = __bio_map_user_iov(q, bdev, iov, iov_count, write_to_vm,
+                                gfp_mask);
        if (IS_ERR(bio))
                return bio;
 
@@ -976,48 +1048,13 @@ static void bio_copy_kern_endio(struct bio *bio, int err)
 struct bio *bio_copy_kern(struct request_queue *q, void *data, unsigned int len,
                          gfp_t gfp_mask, int reading)
 {
-       unsigned long kaddr = (unsigned long)data;
-       unsigned long end = (kaddr + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
-       unsigned long start = kaddr >> PAGE_SHIFT;
-       const int nr_pages = end - start;
        struct bio *bio;
        struct bio_vec *bvec;
-       struct bio_map_data *bmd;
-       int i, ret;
-       struct sg_iovec iov;
-
-       iov.iov_base = data;
-       iov.iov_len = len;
-
-       bmd = bio_alloc_map_data(nr_pages, 1, gfp_mask);
-       if (!bmd)
-               return ERR_PTR(-ENOMEM);
-
-       ret = -ENOMEM;
-       bio = bio_alloc(gfp_mask, nr_pages);
-       if (!bio)
-               goto out_bmd;
-
-       while (len) {
-               struct page *page;
-               unsigned int bytes = PAGE_SIZE;
-
-               if (bytes > len)
-                       bytes = len;
-
-               page = alloc_page(q->bounce_gfp | gfp_mask);
-               if (!page) {
-                       ret = -ENOMEM;
-                       goto cleanup;
-               }
-
-               if (bio_add_pc_page(q, bio, page, bytes, 0) < bytes) {
-                       ret = -EINVAL;
-                       goto cleanup;
-               }
+       int i;
 
-               len -= bytes;
-       }
+       bio = bio_copy_user(q, NULL, (unsigned long)data, len, 1, gfp_mask);
+       if (IS_ERR(bio))
+               return bio;
 
        if (!reading) {
                void *p = data;
@@ -1030,20 +1067,9 @@ struct bio *bio_copy_kern(struct request_queue *q, void *data, unsigned int len,
                }
        }
 
-       bio->bi_private = bmd;
        bio->bi_end_io = bio_copy_kern_endio;
 
-       bio_set_map_data(bmd, bio, &iov, 1);
        return bio;
-cleanup:
-       bio_for_each_segment(bvec, bio, i)
-               __free_page(bvec->bv_page);
-
-       bio_put(bio);
-out_bmd:
-       bio_free_map_data(bmd);
-
-       return ERR_PTR(ret);
 }
 
 /*
@@ -1230,9 +1256,9 @@ static void bio_pair_end_2(struct bio *bi, int err)
  * split a bio - only worry about a bio with a single page
  * in it's iovec
  */
-struct bio_pair *bio_split(struct bio *bi, mempool_t *pool, int first_sectors)
+struct bio_pair *bio_split(struct bio *bi, int first_sectors)
 {
-       struct bio_pair *bp = mempool_alloc(pool, GFP_NOIO);
+       struct bio_pair *bp = mempool_alloc(bio_split_pool, GFP_NOIO);
 
        if (!bp)
                return bp;
@@ -1266,7 +1292,7 @@ struct bio_pair *bio_split(struct bio *bi, mempool_t *pool, int first_sectors)
        bp->bio2.bi_end_io = bio_pair_end_2;
 
        bp->bio1.bi_private = bi;
-       bp->bio2.bi_private = pool;
+       bp->bio2.bi_private = bio_split_pool;
 
        if (bio_integrity(bi))
                bio_integrity_split(bi, bp, first_sectors);
@@ -1274,6 +1300,42 @@ struct bio_pair *bio_split(struct bio *bi, mempool_t *pool, int first_sectors)
        return bp;
 }
 
+/**
+ *      bio_sector_offset - Find hardware sector offset in bio
+ *      @bio:           bio to inspect
+ *      @index:         bio_vec index
+ *      @offset:        offset in bv_page
+ *
+ *      Return the number of hardware sectors between beginning of bio
+ *      and an end point indicated by a bio_vec index and an offset
+ *      within that vector's page.
+ */
+sector_t bio_sector_offset(struct bio *bio, unsigned short index,
+                          unsigned int offset)
+{
+       unsigned int sector_sz = queue_hardsect_size(bio->bi_bdev->bd_disk->queue);
+       struct bio_vec *bv;
+       sector_t sectors;
+       int i;
+
+       sectors = 0;
+
+       if (index >= bio->bi_idx)
+               index = bio->bi_vcnt - 1;
+
+       __bio_for_each_segment(bv, bio, i, 0) {
+               if (i == index) {
+                       if (offset > bv->bv_offset)
+                               sectors += (offset - bv->bv_offset) / sector_sz;
+                       break;
+               }
+
+               sectors += bv->bv_len / sector_sz;
+       }
+
+       return sectors;
+}
+EXPORT_SYMBOL(bio_sector_offset);
 
 /*
  * create memory pools for biovec's in a bio_set.
@@ -1376,6 +1438,7 @@ static int __init init_bio(void)
 subsys_initcall(init_bio);
 
 EXPORT_SYMBOL(bio_alloc);
+EXPORT_SYMBOL(bio_kmalloc);
 EXPORT_SYMBOL(bio_put);
 EXPORT_SYMBOL(bio_free);
 EXPORT_SYMBOL(bio_endio);
@@ -1383,7 +1446,6 @@ EXPORT_SYMBOL(bio_init);
 EXPORT_SYMBOL(__bio_clone);
 EXPORT_SYMBOL(bio_clone);
 EXPORT_SYMBOL(bio_phys_segments);
-EXPORT_SYMBOL(bio_hw_segments);
 EXPORT_SYMBOL(bio_add_page);
 EXPORT_SYMBOL(bio_add_pc_page);
 EXPORT_SYMBOL(bio_get_nr_vecs);
@@ -1393,7 +1455,6 @@ EXPORT_SYMBOL(bio_map_kern);
 EXPORT_SYMBOL(bio_copy_kern);
 EXPORT_SYMBOL(bio_pair_release);
 EXPORT_SYMBOL(bio_split);
-EXPORT_SYMBOL(bio_split_pool);
 EXPORT_SYMBOL(bio_copy_user);
 EXPORT_SYMBOL(bio_uncopy_user);
 EXPORT_SYMBOL(bioset_create);
index aff54219e04953386162690941d7e412f3a29c64..d84f0469a016b0f60a8e6e398190af6c0b091160 100644 (file)
@@ -540,22 +540,6 @@ EXPORT_SYMBOL(bd_release);
  *           /sys/block/sda/holders/dm-0 --> /sys/block/dm-0
  */
 
-static struct kobject *bdev_get_kobj(struct block_device *bdev)
-{
-       if (bdev->bd_contains != bdev)
-               return kobject_get(&bdev->bd_part->dev.kobj);
-       else
-               return kobject_get(&bdev->bd_disk->dev.kobj);
-}
-
-static struct kobject *bdev_get_holder(struct block_device *bdev)
-{
-       if (bdev->bd_contains != bdev)
-               return kobject_get(bdev->bd_part->holder_dir);
-       else
-               return kobject_get(bdev->bd_disk->holder_dir);
-}
-
 static int add_symlink(struct kobject *from, struct kobject *to)
 {
        if (!from || !to)
@@ -604,11 +588,11 @@ static int bd_holder_grab_dirs(struct block_device *bdev,
        if (!bo->hdev)
                goto fail_put_sdir;
 
-       bo->sdev = bdev_get_kobj(bdev);
+       bo->sdev = kobject_get(&part_to_dev(bdev->bd_part)->kobj);
        if (!bo->sdev)
                goto fail_put_hdev;
 
-       bo->hdir = bdev_get_holder(bdev);
+       bo->hdir = kobject_get(bdev->bd_part->holder_dir);
        if (!bo->hdir)
                goto fail_put_sdev;
 
@@ -868,6 +852,87 @@ struct block_device *open_by_devnum(dev_t dev, unsigned mode)
 
 EXPORT_SYMBOL(open_by_devnum);
 
+/**
+ * flush_disk - invalidates all buffer-cache entries on a disk
+ *
+ * @bdev:      struct block device to be flushed
+ *
+ * Invalidates all buffer-cache entries on a disk. It should be called
+ * when a disk has been changed -- either by a media change or online
+ * resize.
+ */
+static void flush_disk(struct block_device *bdev)
+{
+       if (__invalidate_device(bdev)) {
+               char name[BDEVNAME_SIZE] = "";
+
+               if (bdev->bd_disk)
+                       disk_name(bdev->bd_disk, 0, name);
+               printk(KERN_WARNING "VFS: busy inodes on changed media or "
+                      "resized disk %s\n", name);
+       }
+
+       if (!bdev->bd_disk)
+               return;
+       if (disk_partitionable(bdev->bd_disk))
+               bdev->bd_invalidated = 1;
+}
+
+/**
+ * check_disk_size_change - checks for disk size change and adjusts bdev size.
+ * @disk: struct gendisk to check
+ * @bdev: struct bdev to adjust.
+ *
+ * This routine checks to see if the bdev size does not match the disk size
+ * and adjusts it if it differs.
+ */
+void check_disk_size_change(struct gendisk *disk, struct block_device *bdev)
+{
+       loff_t disk_size, bdev_size;
+
+       disk_size = (loff_t)get_capacity(disk) << 9;
+       bdev_size = i_size_read(bdev->bd_inode);
+       if (disk_size != bdev_size) {
+               char name[BDEVNAME_SIZE];
+
+               disk_name(disk, 0, name);
+               printk(KERN_INFO
+                      "%s: detected capacity change from %lld to %lld\n",
+                      name, bdev_size, disk_size);
+               i_size_write(bdev->bd_inode, disk_size);
+               flush_disk(bdev);
+       }
+}
+EXPORT_SYMBOL(check_disk_size_change);
+
+/**
+ * revalidate_disk - wrapper for lower-level driver's revalidate_disk call-back
+ * @disk: struct gendisk to be revalidated
+ *
+ * This routine is a wrapper for lower-level driver's revalidate_disk
+ * call-backs.  It is used to do common pre and post operations needed
+ * for all revalidate_disk operations.
+ */
+int revalidate_disk(struct gendisk *disk)
+{
+       struct block_device *bdev;
+       int ret = 0;
+
+       if (disk->fops->revalidate_disk)
+               ret = disk->fops->revalidate_disk(disk);
+
+       bdev = bdget_disk(disk, 0);
+       if (!bdev)
+               return ret;
+
+       mutex_lock(&bdev->bd_mutex);
+       check_disk_size_change(disk, bdev);
+       mutex_unlock(&bdev->bd_mutex);
+       bdput(bdev);
+       return ret;
+}
+EXPORT_SYMBOL(revalidate_disk);
+
 /*
  * This routine checks whether a removable media has been changed,
  * and invalidates all buffer-cache-entries in that case. This
@@ -887,13 +952,9 @@ int check_disk_change(struct block_device *bdev)
        if (!bdops->media_changed(bdev->bd_disk))
                return 0;
 
-       if (__invalidate_device(bdev))
-               printk("VFS: busy inodes on changed media.\n");
-
+       flush_disk(bdev);
        if (bdops->revalidate_disk)
                bdops->revalidate_disk(bdev->bd_disk);
-       if (bdev->bd_disk->minors > 1)
-               bdev->bd_invalidated = 1;
        return 1;
 }
 
@@ -927,10 +988,10 @@ static int __blkdev_put(struct block_device *bdev, int for_part);
 
 static int do_open(struct block_device *bdev, struct file *file, int for_part)
 {
-       struct module *owner = NULL;
        struct gendisk *disk;
+       struct hd_struct *part = NULL;
        int ret;
-       int part;
+       int partno;
        int perm = 0;
 
        if (file->f_mode & FMODE_READ)
@@ -948,25 +1009,27 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part)
 
        ret = -ENXIO;
        file->f_mapping = bdev->bd_inode->i_mapping;
+
        lock_kernel();
-       disk = get_gendisk(bdev->bd_dev, &part);
-       if (!disk) {
-               unlock_kernel();
-               bdput(bdev);
-               return ret;
-       }
-       owner = disk->fops->owner;
+
+       disk = get_gendisk(bdev->bd_dev, &partno);
+       if (!disk)
+               goto out_unlock_kernel;
+       part = disk_get_part(disk, partno);
+       if (!part)
+               goto out_unlock_kernel;
 
        mutex_lock_nested(&bdev->bd_mutex, for_part);
        if (!bdev->bd_openers) {
                bdev->bd_disk = disk;
+               bdev->bd_part = part;
                bdev->bd_contains = bdev;
-               if (!part) {
+               if (!partno) {
                        struct backing_dev_info *bdi;
                        if (disk->fops->open) {
                                ret = disk->fops->open(bdev->bd_inode, file);
                                if (ret)
-                                       goto out_first;
+                                       goto out_clear;
                        }
                        if (!bdev->bd_openers) {
                                bd_set_size(bdev,(loff_t)get_capacity(disk)<<9);
@@ -978,36 +1041,36 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part)
                        if (bdev->bd_invalidated)
                                rescan_partitions(disk, bdev);
                } else {
-                       struct hd_struct *p;
                        struct block_device *whole;
                        whole = bdget_disk(disk, 0);
                        ret = -ENOMEM;
                        if (!whole)
-                               goto out_first;
+                               goto out_clear;
                        BUG_ON(for_part);
                        ret = __blkdev_get(whole, file->f_mode, file->f_flags, 1);
                        if (ret)
-                               goto out_first;
+                               goto out_clear;
                        bdev->bd_contains = whole;
-                       p = disk->part[part - 1];
                        bdev->bd_inode->i_data.backing_dev_info =
                           whole->bd_inode->i_data.backing_dev_info;
-                       if (!(disk->flags & GENHD_FL_UP) || !p || !p->nr_sects) {
+                       if (!(disk->flags & GENHD_FL_UP) ||
+                           !part || !part->nr_sects) {
                                ret = -ENXIO;
-                               goto out_first;
+                               goto out_clear;
                        }
-                       kobject_get(&p->dev.kobj);
-                       bdev->bd_part = p;
-                       bd_set_size(bdev, (loff_t) p->nr_sects << 9);
+                       bd_set_size(bdev, (loff_t)part->nr_sects << 9);
                }
        } else {
+               disk_put_part(part);
                put_disk(disk);
-               module_put(owner);
+               module_put(disk->fops->owner);
+               part = NULL;
+               disk = NULL;
                if (bdev->bd_contains == bdev) {
                        if (bdev->bd_disk->fops->open) {
                                ret = bdev->bd_disk->fops->open(bdev->bd_inode, file);
                                if (ret)
-                                       goto out;
+                                       goto out_unlock_bdev;
                        }
                        if (bdev->bd_invalidated)
                                rescan_partitions(bdev->bd_disk, bdev);
@@ -1020,19 +1083,24 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part)
        unlock_kernel();
        return 0;
 
-out_first:
+ out_clear:
        bdev->bd_disk = NULL;
+       bdev->bd_part = NULL;
        bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info;
        if (bdev != bdev->bd_contains)
                __blkdev_put(bdev->bd_contains, 1);
        bdev->bd_contains = NULL;
-       put_disk(disk);
-       module_put(owner);
-out:
+ out_unlock_bdev:
        mutex_unlock(&bdev->bd_mutex);
+ out_unlock_kernel:
        unlock_kernel();
-       if (ret)
-               bdput(bdev);
+
+       disk_put_part(part);
+       if (disk)
+               module_put(disk->fops->owner);
+       put_disk(disk);
+       bdput(bdev);
+
        return ret;
 }
 
@@ -1117,11 +1185,8 @@ static int __blkdev_put(struct block_device *bdev, int for_part)
 
                put_disk(disk);
                module_put(owner);
-
-               if (bdev->bd_contains != bdev) {
-                       kobject_put(&bdev->bd_part->dev.kobj);
-                       bdev->bd_part = NULL;
-               }
+               disk_put_part(bdev->bd_part);
+               bdev->bd_part = NULL;
                bdev->bd_disk = NULL;
                bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info;
                if (bdev != bdev->bd_contains)
@@ -1197,10 +1262,9 @@ EXPORT_SYMBOL(ioctl_by_bdev);
 
 /**
  * lookup_bdev  - lookup a struct block_device by name
+ * @pathname:  special file representing the block device
  *
- * @path:      special file representing the block device
- *
- * Get a reference to the blockdevice at @path in the current
+ * Get a reference to the blockdevice at @pathname in the current
  * namespace if possible and return it.  Return ERR_PTR(error)
  * otherwise.
  */
index 89d2fb7b991ae13f1ada96176a5dca785b9dd646..fd9859f92fad3e05ed2ab372d226d6e61fdedfb8 100644 (file)
@@ -14,6 +14,9 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/configfs.h>
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <net/ipv6.h>
 #include <net/sock.h>
 
 #include "config.h"
@@ -377,24 +380,24 @@ static struct config_item_type node_type = {
        .ct_owner = THIS_MODULE,
 };
 
-static struct dlm_cluster *to_cluster(struct config_item *i)
+static struct dlm_cluster *config_item_to_cluster(struct config_item *i)
 {
        return i ? container_of(to_config_group(i), struct dlm_cluster, group) :
                   NULL;
 }
 
-static struct dlm_space *to_space(struct config_item *i)
+static struct dlm_space *config_item_to_space(struct config_item *i)
 {
        return i ? container_of(to_config_group(i), struct dlm_space, group) :
                   NULL;
 }
 
-static struct dlm_comm *to_comm(struct config_item *i)
+static struct dlm_comm *config_item_to_comm(struct config_item *i)
 {
        return i ? container_of(i, struct dlm_comm, item) : NULL;
 }
 
-static struct dlm_node *to_node(struct config_item *i)
+static struct dlm_node *config_item_to_node(struct config_item *i)
 {
        return i ? container_of(i, struct dlm_node, item) : NULL;
 }
@@ -450,7 +453,7 @@ static struct config_group *make_cluster(struct config_group *g,
 
 static void drop_cluster(struct config_group *g, struct config_item *i)
 {
-       struct dlm_cluster *cl = to_cluster(i);
+       struct dlm_cluster *cl = config_item_to_cluster(i);
        struct config_item *tmp;
        int j;
 
@@ -468,7 +471,7 @@ static void drop_cluster(struct config_group *g, struct config_item *i)
 
 static void release_cluster(struct config_item *i)
 {
-       struct dlm_cluster *cl = to_cluster(i);
+       struct dlm_cluster *cl = config_item_to_cluster(i);
        kfree(cl->group.default_groups);
        kfree(cl);
 }
@@ -507,7 +510,7 @@ static struct config_group *make_space(struct config_group *g, const char *name)
 
 static void drop_space(struct config_group *g, struct config_item *i)
 {
-       struct dlm_space *sp = to_space(i);
+       struct dlm_space *sp = config_item_to_space(i);
        struct config_item *tmp;
        int j;
 
@@ -524,7 +527,7 @@ static void drop_space(struct config_group *g, struct config_item *i)
 
 static void release_space(struct config_item *i)
 {
-       struct dlm_space *sp = to_space(i);
+       struct dlm_space *sp = config_item_to_space(i);
        kfree(sp->group.default_groups);
        kfree(sp);
 }
@@ -546,7 +549,7 @@ static struct config_item *make_comm(struct config_group *g, const char *name)
 
 static void drop_comm(struct config_group *g, struct config_item *i)
 {
-       struct dlm_comm *cm = to_comm(i);
+       struct dlm_comm *cm = config_item_to_comm(i);
        if (local_comm == cm)
                local_comm = NULL;
        dlm_lowcomms_close(cm->nodeid);
@@ -557,13 +560,13 @@ static void drop_comm(struct config_group *g, struct config_item *i)
 
 static void release_comm(struct config_item *i)
 {
-       struct dlm_comm *cm = to_comm(i);
+       struct dlm_comm *cm = config_item_to_comm(i);
        kfree(cm);
 }
 
 static struct config_item *make_node(struct config_group *g, const char *name)
 {
-       struct dlm_space *sp = to_space(g->cg_item.ci_parent);
+       struct dlm_space *sp = config_item_to_space(g->cg_item.ci_parent);
        struct dlm_node *nd;
 
        nd = kzalloc(sizeof(struct dlm_node), GFP_KERNEL);
@@ -585,8 +588,8 @@ static struct config_item *make_node(struct config_group *g, const char *name)
 
 static void drop_node(struct config_group *g, struct config_item *i)
 {
-       struct dlm_space *sp = to_space(g->cg_item.ci_parent);
-       struct dlm_node *nd = to_node(i);
+       struct dlm_space *sp = config_item_to_space(g->cg_item.ci_parent);
+       struct dlm_node *nd = config_item_to_node(i);
 
        mutex_lock(&sp->members_lock);
        list_del(&nd->list);
@@ -598,7 +601,7 @@ static void drop_node(struct config_group *g, struct config_item *i)
 
 static void release_node(struct config_item *i)
 {
-       struct dlm_node *nd = to_node(i);
+       struct dlm_node *nd = config_item_to_node(i);
        kfree(nd);
 }
 
@@ -632,7 +635,7 @@ void dlm_config_exit(void)
 static ssize_t show_cluster(struct config_item *i, struct configfs_attribute *a,
                            char *buf)
 {
-       struct dlm_cluster *cl = to_cluster(i);
+       struct dlm_cluster *cl = config_item_to_cluster(i);
        struct cluster_attribute *cla =
                        container_of(a, struct cluster_attribute, attr);
        return cla->show ? cla->show(cl, buf) : 0;
@@ -642,7 +645,7 @@ static ssize_t store_cluster(struct config_item *i,
                             struct configfs_attribute *a,
                             const char *buf, size_t len)
 {
-       struct dlm_cluster *cl = to_cluster(i);
+       struct dlm_cluster *cl = config_item_to_cluster(i);
        struct cluster_attribute *cla =
                container_of(a, struct cluster_attribute, attr);
        return cla->store ? cla->store(cl, buf, len) : -EINVAL;
@@ -651,7 +654,7 @@ static ssize_t store_cluster(struct config_item *i,
 static ssize_t show_comm(struct config_item *i, struct configfs_attribute *a,
                         char *buf)
 {
-       struct dlm_comm *cm = to_comm(i);
+       struct dlm_comm *cm = config_item_to_comm(i);
        struct comm_attribute *cma =
                        container_of(a, struct comm_attribute, attr);
        return cma->show ? cma->show(cm, buf) : 0;
@@ -660,7 +663,7 @@ static ssize_t show_comm(struct config_item *i, struct configfs_attribute *a,
 static ssize_t store_comm(struct config_item *i, struct configfs_attribute *a,
                          const char *buf, size_t len)
 {
-       struct dlm_comm *cm = to_comm(i);
+       struct dlm_comm *cm = config_item_to_comm(i);
        struct comm_attribute *cma =
                container_of(a, struct comm_attribute, attr);
        return cma->store ? cma->store(cm, buf, len) : -EINVAL;
@@ -714,7 +717,7 @@ static ssize_t comm_addr_write(struct dlm_comm *cm, const char *buf, size_t len)
 static ssize_t show_node(struct config_item *i, struct configfs_attribute *a,
                         char *buf)
 {
-       struct dlm_node *nd = to_node(i);
+       struct dlm_node *nd = config_item_to_node(i);
        struct node_attribute *nda =
                        container_of(a, struct node_attribute, attr);
        return nda->show ? nda->show(nd, buf) : 0;
@@ -723,7 +726,7 @@ static ssize_t show_node(struct config_item *i, struct configfs_attribute *a,
 static ssize_t store_node(struct config_item *i, struct configfs_attribute *a,
                          const char *buf, size_t len)
 {
-       struct dlm_node *nd = to_node(i);
+       struct dlm_node *nd = config_item_to_node(i);
        struct node_attribute *nda =
                container_of(a, struct node_attribute, attr);
        return nda->store ? nda->store(nd, buf, len) : -EINVAL;
@@ -768,7 +771,7 @@ static struct dlm_space *get_space(char *name)
        i = config_group_find_item(space_list, name);
        mutex_unlock(&space_list->cg_subsys->su_mutex);
 
-       return to_space(i);
+       return config_item_to_space(i);
 }
 
 static void put_space(struct dlm_space *sp)
@@ -776,6 +779,33 @@ static void put_space(struct dlm_space *sp)
        config_item_put(&sp->group.cg_item);
 }
 
+static int addr_compare(struct sockaddr_storage *x, struct sockaddr_storage *y)
+{
+       switch (x->ss_family) {
+       case AF_INET: {
+               struct sockaddr_in *sinx = (struct sockaddr_in *)x;
+               struct sockaddr_in *siny = (struct sockaddr_in *)y;
+               if (sinx->sin_addr.s_addr != siny->sin_addr.s_addr)
+                       return 0;
+               if (sinx->sin_port != siny->sin_port)
+                       return 0;
+               break;
+       }
+       case AF_INET6: {
+               struct sockaddr_in6 *sinx = (struct sockaddr_in6 *)x;
+               struct sockaddr_in6 *siny = (struct sockaddr_in6 *)y;
+               if (!ipv6_addr_equal(&sinx->sin6_addr, &siny->sin6_addr))
+                       return 0;
+               if (sinx->sin6_port != siny->sin6_port)
+                       return 0;
+               break;
+       }
+       default:
+               return 0;
+       }
+       return 1;
+}
+
 static struct dlm_comm *get_comm(int nodeid, struct sockaddr_storage *addr)
 {
        struct config_item *i;
@@ -788,7 +818,7 @@ static struct dlm_comm *get_comm(int nodeid, struct sockaddr_storage *addr)
        mutex_lock(&clusters_root.subsys.su_mutex);
 
        list_for_each_entry(i, &comm_list->cg_children, ci_entry) {
-               cm = to_comm(i);
+               cm = config_item_to_comm(i);
 
                if (nodeid) {
                        if (cm->nodeid != nodeid)
@@ -797,8 +827,7 @@ static struct dlm_comm *get_comm(int nodeid, struct sockaddr_storage *addr)
                        config_item_get(i);
                        break;
                } else {
-                       if (!cm->addr_count ||
-                           memcmp(cm->addr[0], addr, sizeof(*addr)))
+                       if (!cm->addr_count || !addr_compare(cm->addr[0], addr))
                                continue;
                        found = 1;
                        config_item_get(i);
index 5a7ac33b629cf5db96d6546ee2b394809c4278d3..868e4c9ef1273d1bd75b23aba3afbdf5b8011917 100644 (file)
@@ -2,7 +2,7 @@
 *******************************************************************************
 **
 **  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
-**  Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2004-2008 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -441,8 +441,11 @@ struct dlm_ls {
        uint32_t                ls_global_id;   /* global unique lockspace ID */
        uint32_t                ls_exflags;
        int                     ls_lvblen;
-       int                     ls_count;       /* reference count */
+       int                     ls_count;       /* refcount of processes in
+                                                  the dlm using this ls */
+       int                     ls_create_count; /* create/release refcount */
        unsigned long           ls_flags;       /* LSFL_ */
+       unsigned long           ls_scan_time;
        struct kobject          ls_kobj;
 
        struct dlm_rsbtable     *ls_rsbtbl;
index 499e16759e96fea13329dc05d5408194fa96e4e9..d910501de6d2ca9d4fc8ed1a1cda8d9a1aca1519 100644 (file)
@@ -2,7 +2,7 @@
 *******************************************************************************
 **
 **  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
-**  Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2004-2008 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -23,6 +23,7 @@
 #include "lock.h"
 #include "recover.h"
 #include "requestqueue.h"
+#include "user.h"
 
 static int                     ls_count;
 static struct mutex            ls_lock;
@@ -211,19 +212,41 @@ void dlm_lockspace_exit(void)
        kset_unregister(dlm_kset);
 }
 
+static struct dlm_ls *find_ls_to_scan(void)
+{
+       struct dlm_ls *ls;
+
+       spin_lock(&lslist_lock);
+       list_for_each_entry(ls, &lslist, ls_list) {
+               if (time_after_eq(jiffies, ls->ls_scan_time +
+                                           dlm_config.ci_scan_secs * HZ)) {
+                       spin_unlock(&lslist_lock);
+                       return ls;
+               }
+       }
+       spin_unlock(&lslist_lock);
+       return NULL;
+}
+
 static int dlm_scand(void *data)
 {
        struct dlm_ls *ls;
+       int timeout_jiffies = dlm_config.ci_scan_secs * HZ;
 
        while (!kthread_should_stop()) {
-               list_for_each_entry(ls, &lslist, ls_list) {
+               ls = find_ls_to_scan();
+               if (ls) {
                        if (dlm_lock_recovery_try(ls)) {
+                               ls->ls_scan_time = jiffies;
                                dlm_scan_rsbs(ls);
                                dlm_scan_timeout(ls);
                                dlm_unlock_recovery(ls);
+                       } else {
+                               ls->ls_scan_time += HZ;
                        }
+               } else {
+                       schedule_timeout_interruptible(timeout_jiffies);
                }
-               schedule_timeout_interruptible(dlm_config.ci_scan_secs * HZ);
        }
        return 0;
 }
@@ -246,23 +269,6 @@ static void dlm_scand_stop(void)
        kthread_stop(scand_task);
 }
 
-static struct dlm_ls *dlm_find_lockspace_name(char *name, int namelen)
-{
-       struct dlm_ls *ls;
-
-       spin_lock(&lslist_lock);
-
-       list_for_each_entry(ls, &lslist, ls_list) {
-               if (ls->ls_namelen == namelen &&
-                   memcmp(ls->ls_name, name, namelen) == 0)
-                       goto out;
-       }
-       ls = NULL;
- out:
-       spin_unlock(&lslist_lock);
-       return ls;
-}
-
 struct dlm_ls *dlm_find_lockspace_global(uint32_t id)
 {
        struct dlm_ls *ls;
@@ -327,6 +333,7 @@ static void remove_lockspace(struct dlm_ls *ls)
        for (;;) {
                spin_lock(&lslist_lock);
                if (ls->ls_count == 0) {
+                       WARN_ON(ls->ls_create_count != 0);
                        list_del(&ls->ls_list);
                        spin_unlock(&lslist_lock);
                        return;
@@ -381,7 +388,7 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
                         uint32_t flags, int lvblen)
 {
        struct dlm_ls *ls;
-       int i, size, error = -ENOMEM;
+       int i, size, error;
        int do_unreg = 0;
 
        if (namelen > DLM_LOCKSPACE_LEN)
@@ -393,12 +400,37 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
        if (!try_module_get(THIS_MODULE))
                return -EINVAL;
 
-       ls = dlm_find_lockspace_name(name, namelen);
-       if (ls) {
-               *lockspace = ls;
+       if (!dlm_user_daemon_available()) {
+               module_put(THIS_MODULE);
+               return -EUNATCH;
+       }
+
+       error = 0;
+
+       spin_lock(&lslist_lock);
+       list_for_each_entry(ls, &lslist, ls_list) {
+               WARN_ON(ls->ls_create_count <= 0);
+               if (ls->ls_namelen != namelen)
+                       continue;
+               if (memcmp(ls->ls_name, name, namelen))
+                       continue;
+               if (flags & DLM_LSFL_NEWEXCL) {
+                       error = -EEXIST;
+                       break;
+               }
+               ls->ls_create_count++;
                module_put(THIS_MODULE);
-               return -EEXIST;
+               error = 1; /* not an error, return 0 */
+               break;
        }
+       spin_unlock(&lslist_lock);
+
+       if (error < 0)
+               goto out;
+       if (error)
+               goto ret_zero;
+
+       error = -ENOMEM;
 
        ls = kzalloc(sizeof(struct dlm_ls) + namelen, GFP_KERNEL);
        if (!ls)
@@ -408,6 +440,7 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
        ls->ls_lvblen = lvblen;
        ls->ls_count = 0;
        ls->ls_flags = 0;
+       ls->ls_scan_time = jiffies;
 
        if (flags & DLM_LSFL_TIMEWARN)
                set_bit(LSFL_TIMEWARN, &ls->ls_flags);
@@ -418,8 +451,9 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
                ls->ls_allocation = GFP_KERNEL;
 
        /* ls_exflags are forced to match among nodes, and we don't
-          need to require all nodes to have TIMEWARN or FS set */
-       ls->ls_exflags = (flags & ~(DLM_LSFL_TIMEWARN | DLM_LSFL_FS));
+          need to require all nodes to have some flags set */
+       ls->ls_exflags = (flags & ~(DLM_LSFL_TIMEWARN | DLM_LSFL_FS |
+                                   DLM_LSFL_NEWEXCL));
 
        size = dlm_config.ci_rsbtbl_size;
        ls->ls_rsbtbl_size = size;
@@ -510,6 +544,7 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
        down_write(&ls->ls_in_recovery);
 
        spin_lock(&lslist_lock);
+       ls->ls_create_count = 1;
        list_add(&ls->ls_list, &lslist);
        spin_unlock(&lslist_lock);
 
@@ -548,7 +583,7 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
        dlm_create_debug_file(ls);
 
        log_debug(ls, "join complete");
-
+ ret_zero:
        *lockspace = ls;
        return 0;
 
@@ -635,13 +670,34 @@ static int release_lockspace(struct dlm_ls *ls, int force)
        struct dlm_lkb *lkb;
        struct dlm_rsb *rsb;
        struct list_head *head;
-       int i;
-       int busy = lockspace_busy(ls);
+       int i, busy, rv;
+
+       busy = lockspace_busy(ls);
+
+       spin_lock(&lslist_lock);
+       if (ls->ls_create_count == 1) {
+               if (busy > force)
+                       rv = -EBUSY;
+               else {
+                       /* remove_lockspace takes ls off lslist */
+                       ls->ls_create_count = 0;
+                       rv = 0;
+               }
+       } else if (ls->ls_create_count > 1) {
+               rv = --ls->ls_create_count;
+       } else {
+               rv = -EINVAL;
+       }
+       spin_unlock(&lslist_lock);
 
-       if (busy > force)
-               return -EBUSY;
+       if (rv) {
+               log_debug(ls, "release_lockspace no remove %d", rv);
+               return rv;
+       }
+
+       dlm_device_deregister(ls);
 
-       if (force < 3)
+       if (force < 3 && dlm_user_daemon_available())
                do_uevent(ls, 0);
 
        dlm_recoverd_stop(ls);
@@ -720,15 +776,10 @@ static int release_lockspace(struct dlm_ls *ls, int force)
        dlm_clear_members(ls);
        dlm_clear_members_gone(ls);
        kfree(ls->ls_node_array);
+       log_debug(ls, "release_lockspace final free");
        kobject_put(&ls->ls_kobj);
        /* The ls structure will be freed when the kobject is done with */
 
-       mutex_lock(&ls_lock);
-       ls_count--;
-       if (!ls_count)
-               threads_stop();
-       mutex_unlock(&ls_lock);
-
        module_put(THIS_MODULE);
        return 0;
 }
@@ -750,11 +801,38 @@ static int release_lockspace(struct dlm_ls *ls, int force)
 int dlm_release_lockspace(void *lockspace, int force)
 {
        struct dlm_ls *ls;
+       int error;
 
        ls = dlm_find_lockspace_local(lockspace);
        if (!ls)
                return -EINVAL;
        dlm_put_lockspace(ls);
-       return release_lockspace(ls, force);
+
+       mutex_lock(&ls_lock);
+       error = release_lockspace(ls, force);
+       if (!error)
+               ls_count--;
+       else if (!ls_count)
+               threads_stop();
+       mutex_unlock(&ls_lock);
+
+       return error;
+}
+
+void dlm_stop_lockspaces(void)
+{
+       struct dlm_ls *ls;
+
+ restart:
+       spin_lock(&lslist_lock);
+       list_for_each_entry(ls, &lslist, ls_list) {
+               if (!test_bit(LSFL_RUNNING, &ls->ls_flags))
+                       continue;
+               spin_unlock(&lslist_lock);
+               log_error(ls, "no userland control daemon, stopping lockspace");
+               dlm_ls_stop(ls);
+               goto restart;
+       }
+       spin_unlock(&lslist_lock);
 }
 
index 891eabbdd021e19c92cbe4e996f3f08e0b00253c..f879f87901f804045e2729bbdea094423f8c1500 100644 (file)
@@ -20,6 +20,7 @@ struct dlm_ls *dlm_find_lockspace_global(uint32_t id);
 struct dlm_ls *dlm_find_lockspace_local(void *id);
 struct dlm_ls *dlm_find_lockspace_device(int minor);
 void dlm_put_lockspace(struct dlm_ls *ls);
+void dlm_stop_lockspaces(void);
 
 #endif                         /* __LOCKSPACE_DOT_H__ */
 
index 34f14a14fb4e41e0e8b5b8a0ed207f7f37976703..b3832c67194af2573849df32b337d2096994a082 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2007 Red Hat, Inc.  All rights reserved.
+ * Copyright (C) 2006-2008 Red Hat, Inc.  All rights reserved.
  *
  * This copyrighted material is made available to anyone wishing to use,
  * modify, copy, or redistribute it subject to the terms and conditions
@@ -15,7 +15,6 @@
 #include <linux/poll.h>
 #include <linux/signal.h>
 #include <linux/spinlock.h>
-#include <linux/smp_lock.h>
 #include <linux/dlm.h>
 #include <linux/dlm_device.h>
 
@@ -27,6 +26,8 @@
 
 static const char name_prefix[] = "dlm";
 static const struct file_operations device_fops;
+static atomic_t dlm_monitor_opened;
+static int dlm_monitor_unused = 1;
 
 #ifdef CONFIG_COMPAT
 
@@ -340,10 +341,15 @@ static int device_user_deadlock(struct dlm_user_proc *proc,
        return error;
 }
 
-static int create_misc_device(struct dlm_ls *ls, char *name)
+static int dlm_device_register(struct dlm_ls *ls, char *name)
 {
        int error, len;
 
+       /* The device is already registered.  This happens when the
+          lockspace is created multiple times from userspace. */
+       if (ls->ls_device.name)
+               return 0;
+
        error = -ENOMEM;
        len = strlen(name) + strlen(name_prefix) + 2;
        ls->ls_device.name = kzalloc(len, GFP_KERNEL);
@@ -363,6 +369,22 @@ fail:
        return error;
 }
 
+int dlm_device_deregister(struct dlm_ls *ls)
+{
+       int error;
+
+       /* The device is not registered.  This happens when the lockspace
+          was never used from userspace, or when device_create_lockspace()
+          calls dlm_release_lockspace() after the register fails. */
+       if (!ls->ls_device.name)
+               return 0;
+
+       error = misc_deregister(&ls->ls_device);
+       if (!error)
+               kfree(ls->ls_device.name);
+       return error;
+}
+
 static int device_user_purge(struct dlm_user_proc *proc,
                             struct dlm_purge_params *params)
 {
@@ -397,7 +419,7 @@ static int device_create_lockspace(struct dlm_lspace_params *params)
        if (!ls)
                return -ENOENT;
 
-       error = create_misc_device(ls, params->name);
+       error = dlm_device_register(ls, params->name);
        dlm_put_lockspace(ls);
 
        if (error)
@@ -421,31 +443,22 @@ static int device_remove_lockspace(struct dlm_lspace_params *params)
        if (!ls)
                return -ENOENT;
 
-       /* Deregister the misc device first, so we don't have
-        * a device that's not attached to a lockspace. If
-        * dlm_release_lockspace fails then we can recreate it
-        */
-       error = misc_deregister(&ls->ls_device);
-       if (error) {
-               dlm_put_lockspace(ls);
-               goto out;
-       }
-       kfree(ls->ls_device.name);
-
        if (params->flags & DLM_USER_LSFLG_FORCEFREE)
                force = 2;
 
        lockspace = ls->ls_local_handle;
+       dlm_put_lockspace(ls);
 
-       /* dlm_release_lockspace waits for references to go to zero,
-          so all processes will need to close their device for the ls
-          before the release will procede */
+       /* The final dlm_release_lockspace waits for references to go to
+          zero, so all processes will need to close their device for the
+          ls before the release will proceed.  release also calls the
+          device_deregister above.  Converting a positive return value
+          from release to zero means that userspace won't know when its
+          release was the final one, but it shouldn't need to know. */
 
-       dlm_put_lockspace(ls);
        error = dlm_release_lockspace(lockspace, force);
-       if (error)
-               create_misc_device(ls, ls->ls_name);
- out:
+       if (error > 0)
+               error = 0;
        return error;
 }
 
@@ -623,17 +636,13 @@ static int device_open(struct inode *inode, struct file *file)
        struct dlm_user_proc *proc;
        struct dlm_ls *ls;
 
-       lock_kernel();
        ls = dlm_find_lockspace_device(iminor(inode));
-       if (!ls) {
-               unlock_kernel();
+       if (!ls)
                return -ENOENT;
-       }
 
        proc = kzalloc(sizeof(struct dlm_user_proc), GFP_KERNEL);
        if (!proc) {
                dlm_put_lockspace(ls);
-               unlock_kernel();
                return -ENOMEM;
        }
 
@@ -645,7 +654,6 @@ static int device_open(struct inode *inode, struct file *file)
        spin_lock_init(&proc->locks_spin);
        init_waitqueue_head(&proc->wait);
        file->private_data = proc;
-       unlock_kernel();
 
        return 0;
 }
@@ -878,9 +886,28 @@ static unsigned int device_poll(struct file *file, poll_table *wait)
        return 0;
 }
 
+int dlm_user_daemon_available(void)
+{
+       /* dlm_controld hasn't started (or, has started, but not
+          properly populated configfs) */
+
+       if (!dlm_our_nodeid())
+               return 0;
+
+       /* This is to deal with versions of dlm_controld that don't
+          know about the monitor device.  We assume that if the
+          dlm_controld was started (above), but the monitor device
+          was never opened, that it's an old version.  dlm_controld
+          should open the monitor device before populating configfs. */
+
+       if (dlm_monitor_unused)
+               return 1;
+
+       return atomic_read(&dlm_monitor_opened) ? 1 : 0;
+}
+
 static int ctl_device_open(struct inode *inode, struct file *file)
 {
-       cycle_kernel_lock();
        file->private_data = NULL;
        return 0;
 }
@@ -890,6 +917,20 @@ static int ctl_device_close(struct inode *inode, struct file *file)
        return 0;
 }
 
+static int monitor_device_open(struct inode *inode, struct file *file)
+{
+       atomic_inc(&dlm_monitor_opened);
+       dlm_monitor_unused = 0;
+       return 0;
+}
+
+static int monitor_device_close(struct inode *inode, struct file *file)
+{
+       if (atomic_dec_and_test(&dlm_monitor_opened))
+               dlm_stop_lockspaces();
+       return 0;
+}
+
 static const struct file_operations device_fops = {
        .open    = device_open,
        .release = device_close,
@@ -913,19 +954,42 @@ static struct miscdevice ctl_device = {
        .minor = MISC_DYNAMIC_MINOR,
 };
 
+static const struct file_operations monitor_device_fops = {
+       .open    = monitor_device_open,
+       .release = monitor_device_close,
+       .owner   = THIS_MODULE,
+};
+
+static struct miscdevice monitor_device = {
+       .name  = "dlm-monitor",
+       .fops  = &monitor_device_fops,
+       .minor = MISC_DYNAMIC_MINOR,
+};
+
 int __init dlm_user_init(void)
 {
        int error;
 
+       atomic_set(&dlm_monitor_opened, 0);
+
        error = misc_register(&ctl_device);
-       if (error)
+       if (error) {
                log_print("misc_register failed for control device");
+               goto out;
+       }
 
+       error = misc_register(&monitor_device);
+       if (error) {
+               log_print("misc_register failed for monitor device");
+               misc_deregister(&ctl_device);
+       }
+ out:
        return error;
 }
 
 void dlm_user_exit(void)
 {
        misc_deregister(&ctl_device);
+       misc_deregister(&monitor_device);
 }
 
index d38e9f3e415118b3b4622b9b2909ac269b618c6e..35eb6a13d616d0a946687b809c0881ac1a5c1a12 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 Red Hat, Inc.  All rights reserved.
+ * Copyright (C) 2006-2008 Red Hat, Inc.  All rights reserved.
  *
  * This copyrighted material is made available to anyone wishing to use,
  * modify, copy, or redistribute it subject to the terms and conditions
@@ -12,5 +12,7 @@
 void dlm_user_add_ast(struct dlm_lkb *lkb, int type);
 int dlm_user_init(void);
 void dlm_user_exit(void);
+int dlm_device_deregister(struct dlm_ls *ls);
+int dlm_user_daemon_available(void);
 
 #endif
index 302e95c4af7e0c517704d987932411066c129d86..fb98b3d847ed2d820e6b4425c44ef44e028a66eb 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/msdos_fs.h>
+#include <linux/blkdev.h>
 
 struct fatent_operations {
        void (*ent_blocknr)(struct super_block *, int, int *, sector_t *);
@@ -535,6 +536,7 @@ int fat_free_clusters(struct inode *inode, int cluster)
        struct fat_entry fatent;
        struct buffer_head *bhs[MAX_BUF_PER_PAGE];
        int i, err, nr_bhs;
+       int first_cl = cluster;
 
        nr_bhs = 0;
        fatent_init(&fatent);
@@ -551,6 +553,18 @@ int fat_free_clusters(struct inode *inode, int cluster)
                        goto error;
                }
 
+               /* 
+                * Issue discard for the sectors we no longer care about,
+                * batching contiguous clusters into one request
+                */
+               if (cluster != fatent.entry + 1) {
+                       int nr_clus = fatent.entry - first_cl + 1;
+
+                       sb_issue_discard(sb, fat_clus_to_blknr(sbi, first_cl),
+                                        nr_clus * sbi->sec_per_clus);
+                       first_cl = cluster;
+               }
+
                ops->ent_put(&fatent, FAT_ENT_FREE);
                if (sbi->free_clusters != -1) {
                        sbi->free_clusters++;
index 13391e546616ce47a9b413dde1ac73ad396d808d..c962283d4e7ff174ffe9d2eb719319f863eca2c2 100644 (file)
@@ -1265,6 +1265,8 @@ static void blocking_cb(struct gfs2_sbd *sdp, struct lm_lockname *name,
        holdtime = gl->gl_tchange + gl->gl_ops->go_min_hold_time;
        if (time_before(now, holdtime))
                delay = holdtime - now;
+       if (test_bit(GLF_REPLY_PENDING, &gl->gl_flags))
+               delay = gl->gl_ops->go_min_hold_time;
 
        spin_lock(&gl->gl_spin);
        handle_callback(gl, state, 1, delay);
@@ -1578,8 +1580,6 @@ static const char *hflags2str(char *buf, unsigned flags, unsigned long iflags)
                *p++ = 'a';
        if (flags & GL_EXACT)
                *p++ = 'E';
-       if (flags & GL_ATIME)
-               *p++ = 'a';
        if (flags & GL_NOCACHE)
                *p++ = 'c';
        if (test_bit(HIF_HOLDER, &iflags))
@@ -1816,15 +1816,17 @@ restart:
        if (gl) {
                gi->gl = hlist_entry(gl->gl_list.next,
                                     struct gfs2_glock, gl_list);
-               if (gi->gl)
-                       gfs2_glock_hold(gi->gl);
+       } else {
+               gi->gl = hlist_entry(gl_hash_table[gi->hash].hb_list.first,
+                                    struct gfs2_glock, gl_list);
        }
+       if (gi->gl)
+               gfs2_glock_hold(gi->gl);
        read_unlock(gl_lock_addr(gi->hash));
        if (gl)
                gfs2_glock_put(gl);
-       if (gl && gi->gl == NULL)
-               gi->hash++;
        while (gi->gl == NULL) {
+               gi->hash++;
                if (gi->hash >= GFS2_GL_HASH_SIZE)
                        return 1;
                read_lock(gl_lock_addr(gi->hash));
@@ -1833,7 +1835,6 @@ restart:
                if (gi->gl)
                        gfs2_glock_hold(gi->gl);
                read_unlock(gl_lock_addr(gi->hash));
-               gi->hash++;
        }
 
        if (gi->sdp != gi->gl->gl_sbd)
index 971d92af70fce8ff1e857e73242c322352fcf50c..695c6b1936115c30c267b6b23c219fcca8abc520 100644 (file)
@@ -24,7 +24,6 @@
 #define GL_ASYNC               0x00000040
 #define GL_EXACT               0x00000080
 #define GL_SKIP                        0x00000100
-#define GL_ATIME               0x00000200
 #define GL_NOCACHE             0x00000400
 
 #define GLR_TRYFAILED          13
index 448697a5c462764c18ef977a1432291fc21cc049..f566ec1b4e8efa902c54c4d27ef1c61fac1a8c55 100644 (file)
@@ -386,20 +386,21 @@ struct gfs2_statfs_change_host {
 #define GFS2_DATA_ORDERED      2
 
 struct gfs2_args {
-       char ar_lockproto[GFS2_LOCKNAME_LEN]; /* Name of the Lock Protocol */
-       char ar_locktable[GFS2_LOCKNAME_LEN]; /* Name of the Lock Table */
-       char ar_hostdata[GFS2_LOCKNAME_LEN]; /* Host specific data */
-       int ar_spectator; /* Don't get a journal because we're always RO */
-       int ar_ignore_local_fs; /* Don't optimize even if local_fs is 1 */
-       int ar_localflocks; /* Let the VFS do flock|fcntl locks for us */
-       int ar_localcaching; /* Local-style caching (dangerous on multihost) */
-       int ar_debug; /* Oops on errors instead of trying to be graceful */
-       int ar_upgrade; /* Upgrade ondisk/multihost format */
-       unsigned int ar_num_glockd; /* Number of glockd threads */
-       int ar_posix_acl; /* Enable posix acls */
-       int ar_quota; /* off/account/on */
-       int ar_suiddir; /* suiddir support */
-       int ar_data; /* ordered/writeback */
+       char ar_lockproto[GFS2_LOCKNAME_LEN];   /* Name of the Lock Protocol */
+       char ar_locktable[GFS2_LOCKNAME_LEN];   /* Name of the Lock Table */
+       char ar_hostdata[GFS2_LOCKNAME_LEN];    /* Host specific data */
+       unsigned int ar_spectator:1;            /* Don't get a journal */
+       unsigned int ar_ignore_local_fs:1;      /* Ignore optimisations */
+       unsigned int ar_localflocks:1;          /* Let the VFS do flock|fcntl */
+       unsigned int ar_localcaching:1;         /* Local caching */
+       unsigned int ar_debug:1;                /* Oops on errors */
+       unsigned int ar_upgrade:1;              /* Upgrade ondisk format */
+       unsigned int ar_posix_acl:1;            /* Enable posix acls */
+       unsigned int ar_quota:2;                /* off/account/on */
+       unsigned int ar_suiddir:1;              /* suiddir support */
+       unsigned int ar_data:2;                 /* ordered/writeback */
+       unsigned int ar_meta:1;                 /* mount metafs */
+       unsigned int ar_num_glockd;             /* Number of glockd threads */
 };
 
 struct gfs2_tune {
@@ -419,7 +420,6 @@ struct gfs2_tune {
        unsigned int gt_quota_scale_den; /* Denominator */
        unsigned int gt_quota_cache_secs;
        unsigned int gt_quota_quantum; /* Secs between syncs to quota file */
-       unsigned int gt_atime_quantum; /* Min secs between atime updates */
        unsigned int gt_new_files_jdata;
        unsigned int gt_max_readahead; /* Max bytes to read-ahead from disk */
        unsigned int gt_stall_secs; /* Detects trouble! */
@@ -432,7 +432,7 @@ enum {
        SDF_JOURNAL_CHECKED     = 0,
        SDF_JOURNAL_LIVE        = 1,
        SDF_SHUTDOWN            = 2,
-       SDF_NOATIME             = 3,
+       SDF_NOBARRIERS          = 3,
 };
 
 #define GFS2_FSNAME_LEN                256
@@ -461,7 +461,6 @@ struct gfs2_sb_host {
 
 struct gfs2_sbd {
        struct super_block *sd_vfs;
-       struct super_block *sd_vfs_meta;
        struct kobject sd_kobj;
        unsigned long sd_flags; /* SDF_... */
        struct gfs2_sb_host sd_sb;
@@ -499,7 +498,9 @@ struct gfs2_sbd {
 
        /* Inode Stuff */
 
-       struct inode *sd_master_dir;
+       struct dentry *sd_master_dir;
+       struct dentry *sd_root_dir;
+
        struct inode *sd_jindex;
        struct inode *sd_inum_inode;
        struct inode *sd_statfs_inode;
@@ -634,7 +635,6 @@ struct gfs2_sbd {
        /* Debugging crud */
 
        unsigned long sd_last_warning;
-       struct vfsmount *sd_gfs2mnt;
        struct dentry *debugfs_dir;    /* debugfs directory */
        struct dentry *debugfs_dentry_glocks; /* for debugfs */
 };
index 8b0806a3294863392c914aa262b2a4cb08f4c98e..7cee695fa44163f378293945514b1e4a9bbfd084 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/crc32.h>
 #include <linux/lm_interface.h>
 #include <linux/security.h>
+#include <linux/time.h>
 
 #include "gfs2.h"
 #include "incore.h"
@@ -249,6 +250,7 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
 {
        struct gfs2_dinode_host *di = &ip->i_di;
        const struct gfs2_dinode *str = buf;
+       struct timespec atime;
        u16 height, depth;
 
        if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr)))
@@ -275,8 +277,10 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
        di->di_size = be64_to_cpu(str->di_size);
        i_size_write(&ip->i_inode, di->di_size);
        gfs2_set_inode_blocks(&ip->i_inode, be64_to_cpu(str->di_blocks));
-       ip->i_inode.i_atime.tv_sec = be64_to_cpu(str->di_atime);
-       ip->i_inode.i_atime.tv_nsec = be32_to_cpu(str->di_atime_nsec);
+       atime.tv_sec = be64_to_cpu(str->di_atime);
+       atime.tv_nsec = be32_to_cpu(str->di_atime_nsec);
+       if (timespec_compare(&ip->i_inode.i_atime, &atime) < 0)
+               ip->i_inode.i_atime = atime;
        ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime);
        ip->i_inode.i_mtime.tv_nsec = be32_to_cpu(str->di_mtime_nsec);
        ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime);
@@ -1033,13 +1037,11 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
 
        if (bh)
                brelse(bh);
-       if (!inode)
-               return ERR_PTR(-ENOMEM);
        return inode;
 
 fail_gunlock2:
        gfs2_glock_dq_uninit(ghs + 1);
-       if (inode)
+       if (inode && !IS_ERR(inode))
                iput(inode);
 fail_gunlock:
        gfs2_glock_dq(ghs);
@@ -1140,54 +1142,6 @@ int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name,
        return 0;
 }
 
-/*
- * gfs2_ok_to_move - check if it's ok to move a directory to another directory
- * @this: move this
- * @to: to here
- *
- * Follow @to back to the root and make sure we don't encounter @this
- * Assumes we already hold the rename lock.
- *
- * Returns: errno
- */
-
-int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to)
-{
-       struct inode *dir = &to->i_inode;
-       struct super_block *sb = dir->i_sb;
-       struct inode *tmp;
-       struct qstr dotdot;
-       int error = 0;
-
-       gfs2_str2qstr(&dotdot, "..");
-
-       igrab(dir);
-
-       for (;;) {
-               if (dir == &this->i_inode) {
-                       error = -EINVAL;
-                       break;
-               }
-               if (dir == sb->s_root->d_inode) {
-                       error = 0;
-                       break;
-               }
-
-               tmp = gfs2_lookupi(dir, &dotdot, 1);
-               if (IS_ERR(tmp)) {
-                       error = PTR_ERR(tmp);
-                       break;
-               }
-
-               iput(dir);
-               dir = tmp;
-       }
-
-       iput(dir);
-
-       return error;
-}
-
 /**
  * gfs2_readlinki - return the contents of a symlink
  * @ip: the symlink's inode
@@ -1207,8 +1161,8 @@ int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len)
        unsigned int x;
        int error;
 
-       gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &i_gh);
-       error = gfs2_glock_nq_atime(&i_gh);
+       gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh);
+       error = gfs2_glock_nq(&i_gh);
        if (error) {
                gfs2_holder_uninit(&i_gh);
                return error;
@@ -1243,101 +1197,6 @@ out:
        return error;
 }
 
-/**
- * gfs2_glock_nq_atime - Acquire a hold on an inode's glock, and
- *       conditionally update the inode's atime
- * @gh: the holder to acquire
- *
- * Tests atime (access time) for gfs2_read, gfs2_readdir and gfs2_mmap
- * Update if the difference between the current time and the inode's current
- * atime is greater than an interval specified at mount.
- *
- * Returns: errno
- */
-
-int gfs2_glock_nq_atime(struct gfs2_holder *gh)
-{
-       struct gfs2_glock *gl = gh->gh_gl;
-       struct gfs2_sbd *sdp = gl->gl_sbd;
-       struct gfs2_inode *ip = gl->gl_object;
-       s64 quantum = gfs2_tune_get(sdp, gt_atime_quantum);
-       unsigned int state;
-       int flags;
-       int error;
-       struct timespec tv = CURRENT_TIME;
-
-       if (gfs2_assert_warn(sdp, gh->gh_flags & GL_ATIME) ||
-           gfs2_assert_warn(sdp, !(gh->gh_flags & GL_ASYNC)) ||
-           gfs2_assert_warn(sdp, gl->gl_ops == &gfs2_inode_glops))
-               return -EINVAL;
-
-       state = gh->gh_state;
-       flags = gh->gh_flags;
-
-       error = gfs2_glock_nq(gh);
-       if (error)
-               return error;
-
-       if (test_bit(SDF_NOATIME, &sdp->sd_flags) ||
-           (sdp->sd_vfs->s_flags & MS_RDONLY))
-               return 0;
-
-       if (tv.tv_sec - ip->i_inode.i_atime.tv_sec >= quantum) {
-               gfs2_glock_dq(gh);
-               gfs2_holder_reinit(LM_ST_EXCLUSIVE, gh->gh_flags & ~LM_FLAG_ANY,
-                                  gh);
-               error = gfs2_glock_nq(gh);
-               if (error)
-                       return error;
-
-               /* Verify that atime hasn't been updated while we were
-                  trying to get exclusive lock. */
-
-               tv = CURRENT_TIME;
-               if (tv.tv_sec - ip->i_inode.i_atime.tv_sec >= quantum) {
-                       struct buffer_head *dibh;
-                       struct gfs2_dinode *di;
-
-                       error = gfs2_trans_begin(sdp, RES_DINODE, 0);
-                       if (error == -EROFS)
-                               return 0;
-                       if (error)
-                               goto fail;
-
-                       error = gfs2_meta_inode_buffer(ip, &dibh);
-                       if (error)
-                               goto fail_end_trans;
-
-                       ip->i_inode.i_atime = tv;
-
-                       gfs2_trans_add_bh(ip->i_gl, dibh, 1);
-                       di = (struct gfs2_dinode *)dibh->b_data;
-                       di->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec);
-                       di->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec);
-                       brelse(dibh);
-
-                       gfs2_trans_end(sdp);
-               }
-
-               /* If someone else has asked for the glock,
-                  unlock and let them have it. Then reacquire
-                  in the original state. */
-               if (gfs2_glock_is_blocking(gl)) {
-                       gfs2_glock_dq(gh);
-                       gfs2_holder_reinit(state, flags, gh);
-                       return gfs2_glock_nq(gh);
-               }
-       }
-
-       return 0;
-
-fail_end_trans:
-       gfs2_trans_end(sdp);
-fail:
-       gfs2_glock_dq(gh);
-       return error;
-}
-
 static int
 __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr)
 {
index 58f9607d6a8675694769b978bd93f17e56da47dc..2d43f69610a07c082fbfd0809675b51e4d15b81f 100644 (file)
@@ -91,9 +91,7 @@ int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name,
 int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name,
                   const struct gfs2_inode *ip);
 int gfs2_permission(struct inode *inode, int mask);
-int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to);
 int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len);
-int gfs2_glock_nq_atime(struct gfs2_holder *gh);
 int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr);
 struct inode *gfs2_lookup_simple(struct inode *dip, const char *name);
 void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf);
index 09d78c216f4828792a27a0651a1cd98d6abf5d74..0c4cbe6c82850c20d0ba061476c42030d4321888 100644 (file)
@@ -144,7 +144,8 @@ static int gdlm_mount(char *table_name, char *host_data,
 
        error = dlm_new_lockspace(ls->fsname, strlen(ls->fsname),
                                  &ls->dlm_lockspace,
-                                 DLM_LSFL_FS | (nodir ? DLM_LSFL_NODIR : 0),
+                                 DLM_LSFL_FS | DLM_LSFL_NEWEXCL |
+                                 (nodir ? DLM_LSFL_NODIR : 0),
                                  GDLM_LVB_SIZE);
        if (error) {
                log_error("dlm_new_lockspace error %d", error);
index 6c6af9f5e3ab58373eb897cb1adf2093481a1295..ad305854bdc6bb833b98c37b63ab50578373960f 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/delay.h>
 #include <linux/kthread.h>
 #include <linux/freezer.h>
+#include <linux/bio.h>
 
 #include "gfs2.h"
 #include "incore.h"
@@ -584,7 +585,6 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags, int pull)
        memset(bh->b_data, 0, bh->b_size);
        set_buffer_uptodate(bh);
        clear_buffer_dirty(bh);
-       unlock_buffer(bh);
 
        gfs2_ail1_empty(sdp, 0);
        tail = current_tail(sdp);
@@ -601,8 +601,23 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags, int pull)
        hash = gfs2_disk_hash(bh->b_data, sizeof(struct gfs2_log_header));
        lh->lh_hash = cpu_to_be32(hash);
 
-       set_buffer_dirty(bh);
-       if (sync_dirty_buffer(bh))
+       bh->b_end_io = end_buffer_write_sync;
+       if (test_bit(SDF_NOBARRIERS, &sdp->sd_flags))
+               goto skip_barrier;
+       get_bh(bh);
+       submit_bh(WRITE_BARRIER | (1 << BIO_RW_META), bh);
+       wait_on_buffer(bh);
+       if (buffer_eopnotsupp(bh)) {
+               clear_buffer_eopnotsupp(bh);
+               set_buffer_uptodate(bh);
+               set_bit(SDF_NOBARRIERS, &sdp->sd_flags);
+               lock_buffer(bh);
+skip_barrier:
+               get_bh(bh);
+               submit_bh(WRITE_SYNC | (1 << BIO_RW_META), bh);
+               wait_on_buffer(bh);
+       }
+       if (!buffer_uptodate(bh))
                gfs2_io_error_bh(sdp, bh);
        brelse(bh);
 
index b941f9f9f958e84a1fcf1a1431726e4f399a3b6c..df48333e6f010596b49aa1bba963ae0856213e3d 100644 (file)
@@ -42,6 +42,7 @@ enum {
        Opt_nosuiddir,
        Opt_data_writeback,
        Opt_data_ordered,
+       Opt_meta,
        Opt_err,
 };
 
@@ -66,6 +67,7 @@ static match_table_t tokens = {
        {Opt_nosuiddir, "nosuiddir"},
        {Opt_data_writeback, "data=writeback"},
        {Opt_data_ordered, "data=ordered"},
+       {Opt_meta, "meta"},
        {Opt_err, NULL}
 };
 
@@ -239,6 +241,11 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, char *data_arg, int remount)
                case Opt_data_ordered:
                        args->ar_data = GFS2_DATA_ORDERED;
                        break;
+               case Opt_meta:
+                       if (remount && args->ar_meta != 1)
+                               goto cant_remount;
+                       args->ar_meta = 1;
+                       break;
                case Opt_err:
                default:
                        fs_info(sdp, "unknown option: %s\n", o);
index e64a1b04117ad5b27bb5fc1efd98ffe6295056a8..27563816e1c5a0f086657b12b0fab0cbc861fbef 100644 (file)
@@ -512,8 +512,8 @@ static int gfs2_readpage(struct file *file, struct page *page)
        int error;
 
        unlock_page(page);
-       gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh);
-       error = gfs2_glock_nq_atime(&gh);
+       gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &gh);
+       error = gfs2_glock_nq(&gh);
        if (unlikely(error))
                goto out;
        error = AOP_TRUNCATED_PAGE;
@@ -594,8 +594,8 @@ static int gfs2_readpages(struct file *file, struct address_space *mapping,
        struct gfs2_holder gh;
        int ret;
 
-       gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh);
-       ret = gfs2_glock_nq_atime(&gh);
+       gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &gh);
+       ret = gfs2_glock_nq(&gh);
        if (unlikely(ret))
                goto out_uninit;
        if (!gfs2_is_stuffed(ip))
@@ -636,8 +636,8 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping,
        unsigned to = from + len;
        struct page *page;
 
-       gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_ATIME, &ip->i_gh);
-       error = gfs2_glock_nq_atime(&ip->i_gh);
+       gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ip->i_gh);
+       error = gfs2_glock_nq(&ip->i_gh);
        if (unlikely(error))
                goto out_uninit;
 
@@ -975,7 +975,7 @@ static int gfs2_ok_for_dio(struct gfs2_inode *ip, int rw, loff_t offset)
        if (gfs2_is_stuffed(ip))
                return 0;
 
-       if (offset > i_size_read(&ip->i_inode))
+       if (offset >= i_size_read(&ip->i_inode))
                return 0;
        return 1;
 }
@@ -1000,8 +1000,8 @@ static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb,
         * unfortunately have the option of only flushing a range like
         * the VFS does.
         */
-       gfs2_holder_init(ip->i_gl, LM_ST_DEFERRED, GL_ATIME, &gh);
-       rv = gfs2_glock_nq_atime(&gh);
+       gfs2_holder_init(ip->i_gl, LM_ST_DEFERRED, 0, &gh);
+       rv = gfs2_glock_nq(&gh);
        if (rv)
                return rv;
        rv = gfs2_ok_for_dio(ip, rw, offset);
index e9a366d4411cf2412e82d9e645609c69c0dfcd7d..3a747f8e2188058a2d38fa89913c420268c07e19 100644 (file)
@@ -89,8 +89,8 @@ static int gfs2_readdir(struct file *file, void *dirent, filldir_t filldir)
        u64 offset = file->f_pos;
        int error;
 
-       gfs2_holder_init(dip->i_gl, LM_ST_SHARED, GL_ATIME, &d_gh);
-       error = gfs2_glock_nq_atime(&d_gh);
+       gfs2_holder_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh);
+       error = gfs2_glock_nq(&d_gh);
        if (error) {
                gfs2_holder_uninit(&d_gh);
                return error;
@@ -153,8 +153,8 @@ static int gfs2_get_flags(struct file *filp, u32 __user *ptr)
        int error;
        u32 fsflags;
 
-       gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh);
-       error = gfs2_glock_nq_atime(&gh);
+       gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &gh);
+       error = gfs2_glock_nq(&gh);
        if (error)
                return error;
 
@@ -351,8 +351,8 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct page *page)
        struct gfs2_alloc *al;
        int ret;
 
-       gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_ATIME, &gh);
-       ret = gfs2_glock_nq_atime(&gh);
+       gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
+       ret = gfs2_glock_nq(&gh);
        if (ret)
                goto out;
 
@@ -434,8 +434,8 @@ static int gfs2_mmap(struct file *file, struct vm_area_struct *vma)
        struct gfs2_holder i_gh;
        int error;
 
-       gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &i_gh);
-       error = gfs2_glock_nq_atime(&i_gh);
+       gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh);
+       error = gfs2_glock_nq(&i_gh);
        if (error) {
                gfs2_holder_uninit(&i_gh);
                return error;
index b4d1d6490633dbbe6a0662824526c976ef091d28..b117fcf2c4f5fdfa00b5c7a9d8967bb373f0a2c6 100644 (file)
 #define DO 0
 #define UNDO 1
 
+static const u32 gfs2_old_fs_formats[] = {
+        0
+};
+
+static const u32 gfs2_old_multihost_formats[] = {
+        0
+};
+
+/**
+ * gfs2_tune_init - Fill a gfs2_tune structure with default values
+ * @gt: tune
+ *
+ */
+
+static void gfs2_tune_init(struct gfs2_tune *gt)
+{
+       spin_lock_init(&gt->gt_spin);
+
+       gt->gt_demote_secs = 300;
+       gt->gt_incore_log_blocks = 1024;
+       gt->gt_log_flush_secs = 60;
+       gt->gt_recoverd_secs = 60;
+       gt->gt_logd_secs = 1;
+       gt->gt_quotad_secs = 5;
+       gt->gt_quota_simul_sync = 64;
+       gt->gt_quota_warn_period = 10;
+       gt->gt_quota_scale_num = 1;
+       gt->gt_quota_scale_den = 1;
+       gt->gt_quota_cache_secs = 300;
+       gt->gt_quota_quantum = 60;
+       gt->gt_new_files_jdata = 0;
+       gt->gt_max_readahead = 1 << 18;
+       gt->gt_stall_secs = 600;
+       gt->gt_complain_secs = 10;
+       gt->gt_statfs_quantum = 30;
+       gt->gt_statfs_slow = 0;
+}
+
 static struct gfs2_sbd *init_sbd(struct super_block *sb)
 {
        struct gfs2_sbd *sdp;
@@ -96,21 +134,271 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
        return sdp;
 }
 
-static void init_vfs(struct super_block *sb, unsigned noatime)
+
+/**
+ * gfs2_check_sb - Check superblock
+ * @sdp: the filesystem
+ * @sb: The superblock
+ * @silent: Don't print a message if the check fails
+ *
+ * Checks the version code of the FS is one that we understand how to
+ * read and that the sizes of the various on-disk structures have not
+ * changed.
+ */
+
+static int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb_host *sb, int silent)
 {
-       struct gfs2_sbd *sdp = sb->s_fs_info;
+       unsigned int x;
 
-       sb->s_magic = GFS2_MAGIC;
-       sb->s_op = &gfs2_super_ops;
-       sb->s_export_op = &gfs2_export_ops;
-       sb->s_time_gran = 1;
-       sb->s_maxbytes = MAX_LFS_FILESIZE;
+       if (sb->sb_magic != GFS2_MAGIC ||
+           sb->sb_type != GFS2_METATYPE_SB) {
+               if (!silent)
+                       printk(KERN_WARNING "GFS2: not a GFS2 filesystem\n");
+               return -EINVAL;
+       }
+
+       /*  If format numbers match exactly, we're done.  */
+
+       if (sb->sb_fs_format == GFS2_FORMAT_FS &&
+           sb->sb_multihost_format == GFS2_FORMAT_MULTI)
+               return 0;
+
+       if (sb->sb_fs_format != GFS2_FORMAT_FS) {
+               for (x = 0; gfs2_old_fs_formats[x]; x++)
+                       if (gfs2_old_fs_formats[x] == sb->sb_fs_format)
+                               break;
+
+               if (!gfs2_old_fs_formats[x]) {
+                       printk(KERN_WARNING
+                              "GFS2: code version (%u, %u) is incompatible "
+                              "with ondisk format (%u, %u)\n",
+                              GFS2_FORMAT_FS, GFS2_FORMAT_MULTI,
+                              sb->sb_fs_format, sb->sb_multihost_format);
+                       printk(KERN_WARNING
+                              "GFS2: I don't know how to upgrade this FS\n");
+                       return -EINVAL;
+               }
+       }
+
+       if (sb->sb_multihost_format != GFS2_FORMAT_MULTI) {
+               for (x = 0; gfs2_old_multihost_formats[x]; x++)
+                       if (gfs2_old_multihost_formats[x] ==
+                           sb->sb_multihost_format)
+                               break;
+
+               if (!gfs2_old_multihost_formats[x]) {
+                       printk(KERN_WARNING
+                              "GFS2: code version (%u, %u) is incompatible "
+                              "with ondisk format (%u, %u)\n",
+                              GFS2_FORMAT_FS, GFS2_FORMAT_MULTI,
+                              sb->sb_fs_format, sb->sb_multihost_format);
+                       printk(KERN_WARNING
+                              "GFS2: I don't know how to upgrade this FS\n");
+                       return -EINVAL;
+               }
+       }
+
+       if (!sdp->sd_args.ar_upgrade) {
+               printk(KERN_WARNING
+                      "GFS2: code version (%u, %u) is incompatible "
+                      "with ondisk format (%u, %u)\n",
+                      GFS2_FORMAT_FS, GFS2_FORMAT_MULTI,
+                      sb->sb_fs_format, sb->sb_multihost_format);
+               printk(KERN_INFO
+                      "GFS2: Use the \"upgrade\" mount option to upgrade "
+                      "the FS\n");
+               printk(KERN_INFO "GFS2: See the manual for more details\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static void end_bio_io_page(struct bio *bio, int error)
+{
+       struct page *page = bio->bi_private;
 
-       if (sb->s_flags & (MS_NOATIME | MS_NODIRATIME))
-               set_bit(noatime, &sdp->sd_flags);
+       if (!error)
+               SetPageUptodate(page);
+       else
+               printk(KERN_WARNING "gfs2: error %d reading superblock\n", error);
+       unlock_page(page);
+}
+
+static void gfs2_sb_in(struct gfs2_sb_host *sb, const void *buf)
+{
+       const struct gfs2_sb *str = buf;
+
+       sb->sb_magic = be32_to_cpu(str->sb_header.mh_magic);
+       sb->sb_type = be32_to_cpu(str->sb_header.mh_type);
+       sb->sb_format = be32_to_cpu(str->sb_header.mh_format);
+       sb->sb_fs_format = be32_to_cpu(str->sb_fs_format);
+       sb->sb_multihost_format = be32_to_cpu(str->sb_multihost_format);
+       sb->sb_bsize = be32_to_cpu(str->sb_bsize);
+       sb->sb_bsize_shift = be32_to_cpu(str->sb_bsize_shift);
+       sb->sb_master_dir.no_addr = be64_to_cpu(str->sb_master_dir.no_addr);
+       sb->sb_master_dir.no_formal_ino = be64_to_cpu(str->sb_master_dir.no_formal_ino);
+       sb->sb_root_dir.no_addr = be64_to_cpu(str->sb_root_dir.no_addr);
+       sb->sb_root_dir.no_formal_ino = be64_to_cpu(str->sb_root_dir.no_formal_ino);
+
+       memcpy(sb->sb_lockproto, str->sb_lockproto, GFS2_LOCKNAME_LEN);
+       memcpy(sb->sb_locktable, str->sb_locktable, GFS2_LOCKNAME_LEN);
+}
+
+/**
+ * gfs2_read_super - Read the gfs2 super block from disk
+ * @sdp: The GFS2 super block
+ * @sector: The location of the super block
+ * @error: The error code to return
+ *
+ * This uses the bio functions to read the super block from disk
+ * because we want to be 100% sure that we never read cached data.
+ * A super block is read twice only during each GFS2 mount and is
+ * never written to by the filesystem. The first time its read no
+ * locks are held, and the only details which are looked at are those
+ * relating to the locking protocol. Once locking is up and working,
+ * the sb is read again under the lock to establish the location of
+ * the master directory (contains pointers to journals etc) and the
+ * root directory.
+ *
+ * Returns: 0 on success or error
+ */
+
+static int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector)
+{
+       struct super_block *sb = sdp->sd_vfs;
+       struct gfs2_sb *p;
+       struct page *page;
+       struct bio *bio;
+
+       page = alloc_page(GFP_NOFS);
+       if (unlikely(!page))
+               return -ENOBUFS;
+
+       ClearPageUptodate(page);
+       ClearPageDirty(page);
+       lock_page(page);
+
+       bio = bio_alloc(GFP_NOFS, 1);
+       if (unlikely(!bio)) {
+               __free_page(page);
+               return -ENOBUFS;
+       }
 
-       /* Don't let the VFS update atimes.  GFS2 handles this itself. */
-       sb->s_flags |= MS_NOATIME | MS_NODIRATIME;
+       bio->bi_sector = sector * (sb->s_blocksize >> 9);
+       bio->bi_bdev = sb->s_bdev;
+       bio_add_page(bio, page, PAGE_SIZE, 0);
+
+       bio->bi_end_io = end_bio_io_page;
+       bio->bi_private = page;
+       submit_bio(READ_SYNC | (1 << BIO_RW_META), bio);
+       wait_on_page_locked(page);
+       bio_put(bio);
+       if (!PageUptodate(page)) {
+               __free_page(page);
+               return -EIO;
+       }
+       p = kmap(page);
+       gfs2_sb_in(&sdp->sd_sb, p);
+       kunmap(page);
+       __free_page(page);
+       return 0;
+}
+/**
+ * gfs2_read_sb - Read super block
+ * @sdp: The GFS2 superblock
+ * @gl: the glock for the superblock (assumed to be held)
+ * @silent: Don't print message if mount fails
+ *
+ */
+
+static int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent)
+{
+       u32 hash_blocks, ind_blocks, leaf_blocks;
+       u32 tmp_blocks;
+       unsigned int x;
+       int error;
+
+       error = gfs2_read_super(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift);
+       if (error) {
+               if (!silent)
+                       fs_err(sdp, "can't read superblock\n");
+               return error;
+       }
+
+       error = gfs2_check_sb(sdp, &sdp->sd_sb, silent);
+       if (error)
+               return error;
+
+       sdp->sd_fsb2bb_shift = sdp->sd_sb.sb_bsize_shift -
+                              GFS2_BASIC_BLOCK_SHIFT;
+       sdp->sd_fsb2bb = 1 << sdp->sd_fsb2bb_shift;
+       sdp->sd_diptrs = (sdp->sd_sb.sb_bsize -
+                         sizeof(struct gfs2_dinode)) / sizeof(u64);
+       sdp->sd_inptrs = (sdp->sd_sb.sb_bsize -
+                         sizeof(struct gfs2_meta_header)) / sizeof(u64);
+       sdp->sd_jbsize = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header);
+       sdp->sd_hash_bsize = sdp->sd_sb.sb_bsize / 2;
+       sdp->sd_hash_bsize_shift = sdp->sd_sb.sb_bsize_shift - 1;
+       sdp->sd_hash_ptrs = sdp->sd_hash_bsize / sizeof(u64);
+       sdp->sd_qc_per_block = (sdp->sd_sb.sb_bsize -
+                               sizeof(struct gfs2_meta_header)) /
+                               sizeof(struct gfs2_quota_change);
+
+       /* Compute maximum reservation required to add a entry to a directory */
+
+       hash_blocks = DIV_ROUND_UP(sizeof(u64) * (1 << GFS2_DIR_MAX_DEPTH),
+                            sdp->sd_jbsize);
+
+       ind_blocks = 0;
+       for (tmp_blocks = hash_blocks; tmp_blocks > sdp->sd_diptrs;) {
+               tmp_blocks = DIV_ROUND_UP(tmp_blocks, sdp->sd_inptrs);
+               ind_blocks += tmp_blocks;
+       }
+
+       leaf_blocks = 2 + GFS2_DIR_MAX_DEPTH;
+
+       sdp->sd_max_dirres = hash_blocks + ind_blocks + leaf_blocks;
+
+       sdp->sd_heightsize[0] = sdp->sd_sb.sb_bsize -
+                               sizeof(struct gfs2_dinode);
+       sdp->sd_heightsize[1] = sdp->sd_sb.sb_bsize * sdp->sd_diptrs;
+       for (x = 2;; x++) {
+               u64 space, d;
+               u32 m;
+
+               space = sdp->sd_heightsize[x - 1] * sdp->sd_inptrs;
+               d = space;
+               m = do_div(d, sdp->sd_inptrs);
+
+               if (d != sdp->sd_heightsize[x - 1] || m)
+                       break;
+               sdp->sd_heightsize[x] = space;
+       }
+       sdp->sd_max_height = x;
+       sdp->sd_heightsize[x] = ~0;
+       gfs2_assert(sdp, sdp->sd_max_height <= GFS2_MAX_META_HEIGHT);
+
+       sdp->sd_jheightsize[0] = sdp->sd_sb.sb_bsize -
+                                sizeof(struct gfs2_dinode);
+       sdp->sd_jheightsize[1] = sdp->sd_jbsize * sdp->sd_diptrs;
+       for (x = 2;; x++) {
+               u64 space, d;
+               u32 m;
+
+               space = sdp->sd_jheightsize[x - 1] * sdp->sd_inptrs;
+               d = space;
+               m = do_div(d, sdp->sd_inptrs);
+
+               if (d != sdp->sd_jheightsize[x - 1] || m)
+                       break;
+               sdp->sd_jheightsize[x] = space;
+       }
+       sdp->sd_max_jheight = x;
+       sdp->sd_jheightsize[x] = ~0;
+       gfs2_assert(sdp, sdp->sd_max_jheight <= GFS2_MAX_META_HEIGHT);
+
+       return 0;
 }
 
 static int init_names(struct gfs2_sbd *sdp, int silent)
@@ -224,51 +512,59 @@ fail:
        return error;
 }
 
-static inline struct inode *gfs2_lookup_root(struct super_block *sb,
-                                            u64 no_addr)
+static int gfs2_lookup_root(struct super_block *sb, struct dentry **dptr,
+                           u64 no_addr, const char *name)
 {
-       return gfs2_inode_lookup(sb, DT_DIR, no_addr, 0, 0);
+       struct gfs2_sbd *sdp = sb->s_fs_info;
+       struct dentry *dentry;
+       struct inode *inode;
+
+       inode = gfs2_inode_lookup(sb, DT_DIR, no_addr, 0, 0);
+       if (IS_ERR(inode)) {
+               fs_err(sdp, "can't read in %s inode: %ld\n", name, PTR_ERR(inode));
+               return PTR_ERR(inode);
+       }
+       dentry = d_alloc_root(inode);
+       if (!dentry) {
+               fs_err(sdp, "can't alloc %s dentry\n", name);
+               iput(inode);
+               return -ENOMEM;
+       }
+       dentry->d_op = &gfs2_dops;
+       *dptr = dentry;
+       return 0;
 }
 
-static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
+static int init_sb(struct gfs2_sbd *sdp, int silent)
 {
        struct super_block *sb = sdp->sd_vfs;
        struct gfs2_holder sb_gh;
        u64 no_addr;
-       struct inode *inode;
-       int error = 0;
+       int ret;
 
-       if (undo) {
-               if (sb->s_root) {
-                       dput(sb->s_root);
-                       sb->s_root = NULL;
-               }
-               return 0;
+       ret = gfs2_glock_nq_num(sdp, GFS2_SB_LOCK, &gfs2_meta_glops,
+                               LM_ST_SHARED, 0, &sb_gh);
+       if (ret) {
+               fs_err(sdp, "can't acquire superblock glock: %d\n", ret);
+               return ret;
        }
 
-       error = gfs2_glock_nq_num(sdp, GFS2_SB_LOCK, &gfs2_meta_glops,
-                                LM_ST_SHARED, 0, &sb_gh);
-       if (error) {
-               fs_err(sdp, "can't acquire superblock glock: %d\n", error);
-               return error;
-       }
-
-       error = gfs2_read_sb(sdp, sb_gh.gh_gl, silent);
-       if (error) {
-               fs_err(sdp, "can't read superblock: %d\n", error);
+       ret = gfs2_read_sb(sdp, sb_gh.gh_gl, silent);
+       if (ret) {
+               fs_err(sdp, "can't read superblock: %d\n", ret);
                goto out;
        }
 
        /* Set up the buffer cache and SB for real */
        if (sdp->sd_sb.sb_bsize < bdev_hardsect_size(sb->s_bdev)) {
-               error = -EINVAL;
+               ret = -EINVAL;
                fs_err(sdp, "FS block size (%u) is too small for device "
                       "block size (%u)\n",
                       sdp->sd_sb.sb_bsize, bdev_hardsect_size(sb->s_bdev));
                goto out;
        }
        if (sdp->sd_sb.sb_bsize > PAGE_SIZE) {
-               error = -EINVAL;
+               ret = -EINVAL;
                fs_err(sdp, "FS block size (%u) is too big for machine "
                       "page size (%u)\n",
                       sdp->sd_sb.sb_bsize, (unsigned int)PAGE_SIZE);
@@ -278,26 +574,21 @@ static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
 
        /* Get the root inode */
        no_addr = sdp->sd_sb.sb_root_dir.no_addr;
-       if (sb->s_type == &gfs2meta_fs_type)
-               no_addr = sdp->sd_sb.sb_master_dir.no_addr;
-       inode = gfs2_lookup_root(sb, no_addr);
-       if (IS_ERR(inode)) {
-               error = PTR_ERR(inode);
-               fs_err(sdp, "can't read in root inode: %d\n", error);
+       ret = gfs2_lookup_root(sb, &sdp->sd_root_dir, no_addr, "root");
+       if (ret)
                goto out;
-       }
 
-       sb->s_root = d_alloc_root(inode);
-       if (!sb->s_root) {
-               fs_err(sdp, "can't get root dentry\n");
-               error = -ENOMEM;
-               iput(inode);
-       } else
-               sb->s_root->d_op = &gfs2_dops;
-       
+       /* Get the master inode */
+       no_addr = sdp->sd_sb.sb_master_dir.no_addr;
+       ret = gfs2_lookup_root(sb, &sdp->sd_master_dir, no_addr, "master");
+       if (ret) {
+               dput(sdp->sd_root_dir);
+               goto out;
+       }
+       sb->s_root = dget(sdp->sd_args.ar_meta ? sdp->sd_master_dir : sdp->sd_root_dir);
 out:
        gfs2_glock_dq_uninit(&sb_gh);
-       return error;
+       return ret;
 }
 
 /**
@@ -372,6 +663,7 @@ static void gfs2_lm_others_may_mount(struct gfs2_sbd *sdp)
 
 static int init_journal(struct gfs2_sbd *sdp, int undo)
 {
+       struct inode *master = sdp->sd_master_dir->d_inode;
        struct gfs2_holder ji_gh;
        struct task_struct *p;
        struct gfs2_inode *ip;
@@ -383,7 +675,7 @@ static int init_journal(struct gfs2_sbd *sdp, int undo)
                goto fail_recoverd;
        }
 
-       sdp->sd_jindex = gfs2_lookup_simple(sdp->sd_master_dir, "jindex");
+       sdp->sd_jindex = gfs2_lookup_simple(master, "jindex");
        if (IS_ERR(sdp->sd_jindex)) {
                fs_err(sdp, "can't lookup journal index: %d\n", error);
                return PTR_ERR(sdp->sd_jindex);
@@ -506,25 +798,17 @@ static int init_inodes(struct gfs2_sbd *sdp, int undo)
 {
        int error = 0;
        struct gfs2_inode *ip;
-       struct inode *inode;
+       struct inode *master = sdp->sd_master_dir->d_inode;
 
        if (undo)
                goto fail_qinode;
 
-       inode = gfs2_lookup_root(sdp->sd_vfs, sdp->sd_sb.sb_master_dir.no_addr);
-       if (IS_ERR(inode)) {
-               error = PTR_ERR(inode);
-               fs_err(sdp, "can't read in master directory: %d\n", error);
-               goto fail;
-       }
-       sdp->sd_master_dir = inode;
-
        error = init_journal(sdp, undo);
        if (error)
-               goto fail_master;
+               goto fail;
 
        /* Read in the master inode number inode */
-       sdp->sd_inum_inode = gfs2_lookup_simple(sdp->sd_master_dir, "inum");
+       sdp->sd_inum_inode = gfs2_lookup_simple(master, "inum");
        if (IS_ERR(sdp->sd_inum_inode)) {
                error = PTR_ERR(sdp->sd_inum_inode);
                fs_err(sdp, "can't read in inum inode: %d\n", error);
@@ -533,7 +817,7 @@ static int init_inodes(struct gfs2_sbd *sdp, int undo)
 
 
        /* Read in the master statfs inode */
-       sdp->sd_statfs_inode = gfs2_lookup_simple(sdp->sd_master_dir, "statfs");
+       sdp->sd_statfs_inode = gfs2_lookup_simple(master, "statfs");
        if (IS_ERR(sdp->sd_statfs_inode)) {
                error = PTR_ERR(sdp->sd_statfs_inode);
                fs_err(sdp, "can't read in statfs inode: %d\n", error);
@@ -541,7 +825,7 @@ static int init_inodes(struct gfs2_sbd *sdp, int undo)
        }
 
        /* Read in the resource index inode */
-       sdp->sd_rindex = gfs2_lookup_simple(sdp->sd_master_dir, "rindex");
+       sdp->sd_rindex = gfs2_lookup_simple(master, "rindex");
        if (IS_ERR(sdp->sd_rindex)) {
                error = PTR_ERR(sdp->sd_rindex);
                fs_err(sdp, "can't get resource index inode: %d\n", error);
@@ -552,7 +836,7 @@ static int init_inodes(struct gfs2_sbd *sdp, int undo)
        sdp->sd_rindex_uptodate = 0;
 
        /* Read in the quota inode */
-       sdp->sd_quota_inode = gfs2_lookup_simple(sdp->sd_master_dir, "quota");
+       sdp->sd_quota_inode = gfs2_lookup_simple(master, "quota");
        if (IS_ERR(sdp->sd_quota_inode)) {
                error = PTR_ERR(sdp->sd_quota_inode);
                fs_err(sdp, "can't get quota file inode: %d\n", error);
@@ -571,8 +855,6 @@ fail_inum:
        iput(sdp->sd_inum_inode);
 fail_journal:
        init_journal(sdp, UNDO);
-fail_master:
-       iput(sdp->sd_master_dir);
 fail:
        return error;
 }
@@ -583,6 +865,7 @@ static int init_per_node(struct gfs2_sbd *sdp, int undo)
        char buf[30];
        int error = 0;
        struct gfs2_inode *ip;
+       struct inode *master = sdp->sd_master_dir->d_inode;
 
        if (sdp->sd_args.ar_spectator)
                return 0;
@@ -590,7 +873,7 @@ static int init_per_node(struct gfs2_sbd *sdp, int undo)
        if (undo)
                goto fail_qc_gh;
 
-       pn = gfs2_lookup_simple(sdp->sd_master_dir, "per_node");
+       pn = gfs2_lookup_simple(master, "per_node");
        if (IS_ERR(pn)) {
                error = PTR_ERR(pn);
                fs_err(sdp, "can't find per_node directory: %d\n", error);
@@ -800,7 +1083,11 @@ static int fill_super(struct super_block *sb, void *data, int silent)
                goto fail;
        }
 
-       init_vfs(sb, SDF_NOATIME);
+       sb->s_magic = GFS2_MAGIC;
+       sb->s_op = &gfs2_super_ops;
+       sb->s_export_op = &gfs2_export_ops;
+       sb->s_time_gran = 1;
+       sb->s_maxbytes = MAX_LFS_FILESIZE;
 
        /* Set up the buffer cache and fill in some fake block size values
           to allow us to read-in the on-disk superblock. */
@@ -828,7 +1115,7 @@ static int fill_super(struct super_block *sb, void *data, int silent)
        if (error)
                goto fail_lm;
 
-       error = init_sb(sdp, silent, DO);
+       error = init_sb(sdp, silent);
        if (error)
                goto fail_locking;
 
@@ -869,7 +1156,11 @@ fail_per_node:
 fail_inodes:
        init_inodes(sdp, UNDO);
 fail_sb:
-       init_sb(sdp, 0, UNDO);
+       if (sdp->sd_root_dir)
+               dput(sdp->sd_root_dir);
+       if (sdp->sd_master_dir)
+               dput(sdp->sd_master_dir);
+       sb->s_root = NULL;
 fail_locking:
        init_locking(sdp, &mount_gh, UNDO);
 fail_lm:
@@ -887,151 +1178,63 @@ fail:
 }
 
 static int gfs2_get_sb(struct file_system_type *fs_type, int flags,
-               const char *dev_name, void *data, struct vfsmount *mnt)
+                      const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       struct super_block *sb;
-       struct gfs2_sbd *sdp;
-       int error = get_sb_bdev(fs_type, flags, dev_name, data, fill_super, mnt);
-       if (error)
-               goto out;
-       sb = mnt->mnt_sb;
-       sdp = sb->s_fs_info;
-       sdp->sd_gfs2mnt = mnt;
-out:
-       return error;
+       return get_sb_bdev(fs_type, flags, dev_name, data, fill_super, mnt);
 }
 
-static int fill_super_meta(struct super_block *sb, struct super_block *new,
-                          void *data, int silent)
+static struct super_block *get_gfs2_sb(const char *dev_name)
 {
-       struct gfs2_sbd *sdp = sb->s_fs_info;
-       struct inode *inode;
-       int error = 0;
-
-       new->s_fs_info = sdp;
-       sdp->sd_vfs_meta = sb;
-
-       init_vfs(new, SDF_NOATIME);
-
-        /* Get the master inode */
-       inode = igrab(sdp->sd_master_dir);
-
-       new->s_root = d_alloc_root(inode);
-       if (!new->s_root) {
-               fs_err(sdp, "can't get root dentry\n");
-               error = -ENOMEM;
-               iput(inode);
-       } else
-               new->s_root->d_op = &gfs2_dops;
-
-       return error;
-}
-
-static int set_bdev_super(struct super_block *s, void *data)
-{
-       s->s_bdev = data;
-       s->s_dev = s->s_bdev->bd_dev;
-       return 0;
-}
-
-static int test_bdev_super(struct super_block *s, void *data)
-{
-       return s->s_bdev == data;
-}
-
-static struct super_block* get_gfs2_sb(const char *dev_name)
-{
-       struct kstat stat;
+       struct super_block *sb;
        struct nameidata nd;
-       struct super_block *sb = NULL, *s;
        int error;
 
        error = path_lookup(dev_name, LOOKUP_FOLLOW, &nd);
        if (error) {
-               printk(KERN_WARNING "GFS2: path_lookup on %s returned error\n",
-                      dev_name);
-               goto out;
-       }
-       error = vfs_getattr(nd.path.mnt, nd.path.dentry, &stat);
-
-       list_for_each_entry(s, &gfs2_fs_type.fs_supers, s_instances) {
-               if ((S_ISBLK(stat.mode) && s->s_dev == stat.rdev) ||
-                   (S_ISDIR(stat.mode) &&
-                    s == nd.path.dentry->d_inode->i_sb)) {
-                       sb = s;
-                       goto free_nd;
-               }
+               printk(KERN_WARNING "GFS2: path_lookup on %s returned error %d\n",
+                      dev_name, error);
+               return NULL;
        }
-
-       printk(KERN_WARNING "GFS2: Unrecognized block device or "
-              "mount point %s\n", dev_name);
-
-free_nd:
+       sb = nd.path.dentry->d_inode->i_sb;
+       if (sb && (sb->s_type == &gfs2_fs_type))
+               atomic_inc(&sb->s_active);
+       else
+               sb = NULL;
        path_put(&nd.path);
-out:
        return sb;
 }
 
 static int gfs2_get_sb_meta(struct file_system_type *fs_type, int flags,
                            const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       int error = 0;
-       struct super_block *sb = NULL, *new;
+       struct super_block *sb = NULL;
        struct gfs2_sbd *sdp;
 
        sb = get_gfs2_sb(dev_name);
        if (!sb) {
                printk(KERN_WARNING "GFS2: gfs2 mount does not exist\n");
-               error = -ENOENT;
-               goto error;
+               return -ENOENT;
        }
        sdp = sb->s_fs_info;
-       if (sdp->sd_vfs_meta) {
-               printk(KERN_WARNING "GFS2: gfs2meta mount already exists\n");
-               error = -EBUSY;
-               goto error;
-       }
-       down(&sb->s_bdev->bd_mount_sem);
-       new = sget(fs_type, test_bdev_super, set_bdev_super, sb->s_bdev);
-       up(&sb->s_bdev->bd_mount_sem);
-       if (IS_ERR(new)) {
-               error = PTR_ERR(new);
-               goto error;
-       }
-       new->s_flags = flags;
-       strlcpy(new->s_id, sb->s_id, sizeof(new->s_id));
-       sb_set_blocksize(new, sb->s_blocksize);
-       error = fill_super_meta(sb, new, data, flags & MS_SILENT ? 1 : 0);
-       if (error) {
-               up_write(&new->s_umount);
-               deactivate_super(new);
-               goto error;
-       }
-
-       new->s_flags |= MS_ACTIVE;
-
-       /* Grab a reference to the gfs2 mount point */
-       atomic_inc(&sdp->sd_gfs2mnt->mnt_count);
-       return simple_set_mnt(mnt, new);
-error:
-       return error;
+       mnt->mnt_sb = sb;
+       mnt->mnt_root = dget(sdp->sd_master_dir);
+       return 0;
 }
 
 static void gfs2_kill_sb(struct super_block *sb)
 {
-       if (sb->s_fs_info) {
-               gfs2_delete_debugfs_file(sb->s_fs_info);
-               gfs2_meta_syncfs(sb->s_fs_info);
+       struct gfs2_sbd *sdp = sb->s_fs_info;
+       if (sdp) {
+               gfs2_meta_syncfs(sdp);
+               dput(sdp->sd_root_dir);
+               dput(sdp->sd_master_dir);
+               sdp->sd_root_dir = NULL;
+               sdp->sd_master_dir = NULL;
        }
+       shrink_dcache_sb(sb);
        kill_block_super(sb);
-}
-
-static void gfs2_kill_sb_meta(struct super_block *sb)
-{
-       struct gfs2_sbd *sdp = sb->s_fs_info;
-       generic_shutdown_super(sb);
-       sdp->sd_vfs_meta = NULL;
-       atomic_dec(&sdp->sd_gfs2mnt->mnt_count);
+       if (sdp)
+               gfs2_delete_debugfs_file(sdp);
 }
 
 struct file_system_type gfs2_fs_type = {
@@ -1046,7 +1249,6 @@ struct file_system_type gfs2meta_fs_type = {
        .name = "gfs2meta",
        .fs_flags = FS_REQUIRES_DEV,
        .get_sb = gfs2_get_sb_meta,
-       .kill_sb = gfs2_kill_sb_meta,
        .owner = THIS_MODULE,
 };
 
index e2c62f73a7783db388f8da70fee51874cf9e4879..534e1e2c65ca63b3303cbeef81789ad82d893ea2 100644 (file)
@@ -159,9 +159,13 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
        gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
        gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1);
 
-       error = gfs2_glock_nq_m(2, ghs);
+       error = gfs2_glock_nq(ghs); /* parent */
        if (error)
-               goto out;
+               goto out_parent;
+
+       error = gfs2_glock_nq(ghs + 1); /* child */
+       if (error)
+               goto out_child;
 
        error = gfs2_permission(dir, MAY_WRITE | MAY_EXEC);
        if (error)
@@ -245,8 +249,10 @@ out_alloc:
        if (alloc_required)
                gfs2_alloc_put(dip);
 out_gunlock:
-       gfs2_glock_dq_m(2, ghs);
-out:
+       gfs2_glock_dq(ghs + 1);
+out_child:
+       gfs2_glock_dq(ghs);
+out_parent:
        gfs2_holder_uninit(ghs);
        gfs2_holder_uninit(ghs + 1);
        if (!error) {
@@ -302,7 +308,7 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry)
 
        error = gfs2_unlink_ok(dip, &dentry->d_name, ip);
        if (error)
-               goto out_rgrp;
+               goto out_gunlock;
 
        error = gfs2_trans_begin(sdp, 2*RES_DINODE + RES_LEAF + RES_RG_BIT, 0);
        if (error)
@@ -316,6 +322,7 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry)
 
 out_end_trans:
        gfs2_trans_end(sdp);
+out_gunlock:
        gfs2_glock_dq(ghs + 2);
 out_rgrp:
        gfs2_holder_uninit(ghs + 2);
@@ -485,7 +492,6 @@ static int gfs2_rmdir(struct inode *dir, struct dentry *dentry)
        struct gfs2_holder ri_gh;
        int error;
 
-
        error = gfs2_rindex_hold(sdp, &ri_gh);
        if (error)
                return error;
@@ -495,9 +501,17 @@ static int gfs2_rmdir(struct inode *dir, struct dentry *dentry)
        rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr);
        gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2);
 
-       error = gfs2_glock_nq_m(3, ghs);
+       error = gfs2_glock_nq(ghs); /* parent */
        if (error)
-               goto out;
+               goto out_parent;
+
+       error = gfs2_glock_nq(ghs + 1); /* child */
+       if (error)
+               goto out_child;
+
+       error = gfs2_glock_nq(ghs + 2); /* rgrp */
+       if (error)
+               goto out_rgrp;
 
        error = gfs2_unlink_ok(dip, &dentry->d_name, ip);
        if (error)
@@ -523,11 +537,15 @@ static int gfs2_rmdir(struct inode *dir, struct dentry *dentry)
        gfs2_trans_end(sdp);
 
 out_gunlock:
-       gfs2_glock_dq_m(3, ghs);
-out:
-       gfs2_holder_uninit(ghs);
-       gfs2_holder_uninit(ghs + 1);
+       gfs2_glock_dq(ghs + 2);
+out_rgrp:
        gfs2_holder_uninit(ghs + 2);
+       gfs2_glock_dq(ghs + 1);
+out_child:
+       gfs2_holder_uninit(ghs + 1);
+       gfs2_glock_dq(ghs);
+out_parent:
+       gfs2_holder_uninit(ghs);
        gfs2_glock_dq_uninit(&ri_gh);
        return error;
 }
@@ -571,6 +589,54 @@ static int gfs2_mknod(struct inode *dir, struct dentry *dentry, int mode,
        return 0;
 }
 
+/*
+ * gfs2_ok_to_move - check if it's ok to move a directory to another directory
+ * @this: move this
+ * @to: to here
+ *
+ * Follow @to back to the root and make sure we don't encounter @this
+ * Assumes we already hold the rename lock.
+ *
+ * Returns: errno
+ */
+
+static int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to)
+{
+       struct inode *dir = &to->i_inode;
+       struct super_block *sb = dir->i_sb;
+       struct inode *tmp;
+       struct qstr dotdot;
+       int error = 0;
+
+       gfs2_str2qstr(&dotdot, "..");
+
+       igrab(dir);
+
+       for (;;) {
+               if (dir == &this->i_inode) {
+                       error = -EINVAL;
+                       break;
+               }
+               if (dir == sb->s_root->d_inode) {
+                       error = 0;
+                       break;
+               }
+
+               tmp = gfs2_lookupi(dir, &dotdot, 1);
+               if (IS_ERR(tmp)) {
+                       error = PTR_ERR(tmp);
+                       break;
+               }
+
+               iput(dir);
+               dir = tmp;
+       }
+
+       iput(dir);
+
+       return error;
+}
+
 /**
  * gfs2_rename - Rename a file
  * @odir: Parent directory of old file name
@@ -589,7 +655,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
        struct gfs2_inode *ip = GFS2_I(odentry->d_inode);
        struct gfs2_inode *nip = NULL;
        struct gfs2_sbd *sdp = GFS2_SB(odir);
-       struct gfs2_holder ghs[5], r_gh;
+       struct gfs2_holder ghs[5], r_gh = { .gh_gl = NULL, };
        struct gfs2_rgrpd *nrgd;
        unsigned int num_gh;
        int dir_rename = 0;
@@ -603,19 +669,20 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
                        return 0;
        }
 
-       /* Make sure we aren't trying to move a dirctory into it's subdir */
-
-       if (S_ISDIR(ip->i_inode.i_mode) && odip != ndip) {
-               dir_rename = 1;
 
-               error = gfs2_glock_nq_init(sdp->sd_rename_gl, LM_ST_EXCLUSIVE, 0,
-                                          &r_gh);
+       if (odip != ndip) {
+               error = gfs2_glock_nq_init(sdp->sd_rename_gl, LM_ST_EXCLUSIVE,
+                                          0, &r_gh);
                if (error)
                        goto out;
 
-               error = gfs2_ok_to_move(ip, ndip);
-               if (error)
-                       goto out_gunlock_r;
+               if (S_ISDIR(ip->i_inode.i_mode)) {
+                       dir_rename = 1;
+                       /* don't move a dirctory into it's subdir */
+                       error = gfs2_ok_to_move(ip, ndip);
+                       if (error)
+                               goto out_gunlock_r;
+               }
        }
 
        num_gh = 1;
@@ -639,9 +706,11 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
                        gfs2_holder_init(nrgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh++);
        }
 
-       error = gfs2_glock_nq_m(num_gh, ghs);
-       if (error)
-               goto out_uninit;
+       for (x = 0; x < num_gh; x++) {
+               error = gfs2_glock_nq(ghs + x);
+               if (error)
+                       goto out_gunlock;
+       }
 
        /* Check out the old directory */
 
@@ -804,12 +873,12 @@ out_alloc:
        if (alloc_required)
                gfs2_alloc_put(ndip);
 out_gunlock:
-       gfs2_glock_dq_m(num_gh, ghs);
-out_uninit:
-       for (x = 0; x < num_gh; x++)
+       while (x--) {
+               gfs2_glock_dq(ghs + x);
                gfs2_holder_uninit(ghs + x);
+       }
 out_gunlock_r:
-       if (dir_rename)
+       if (r_gh.gh_gl)
                gfs2_glock_dq_uninit(&r_gh);
 out:
        return error;
index f66ea0f7a356bc433663da8011373a25e5fb48ec..d5355d9b59262a9f6de46eea51835fb9360aad50 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/gfs2_ondisk.h>
 #include <linux/crc32.h>
 #include <linux/lm_interface.h>
+#include <linux/time.h>
 
 #include "gfs2.h"
 #include "incore.h"
@@ -38,6 +39,7 @@
 #include "dir.h"
 #include "eattr.h"
 #include "bmap.h"
+#include "meta_io.h"
 
 /**
  * gfs2_write_inode - Make sure the inode is stable on the disk
 static int gfs2_write_inode(struct inode *inode, int sync)
 {
        struct gfs2_inode *ip = GFS2_I(inode);
-
-       /* Check this is a "normal" inode */
-       if (test_bit(GIF_USER, &ip->i_flags)) {
-               if (current->flags & PF_MEMALLOC)
-                       return 0;
-               if (sync)
-                       gfs2_log_flush(GFS2_SB(inode), ip->i_gl);
+       struct gfs2_sbd *sdp = GFS2_SB(inode);
+       struct gfs2_holder gh;
+       struct buffer_head *bh;
+       struct timespec atime;
+       struct gfs2_dinode *di;
+       int ret = 0;
+
+       /* Check this is a "normal" inode, etc */
+       if (!test_bit(GIF_USER, &ip->i_flags) ||
+           (current->flags & PF_MEMALLOC))
+               return 0;
+       ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
+       if (ret)
+               goto do_flush;
+       ret = gfs2_trans_begin(sdp, RES_DINODE, 0);
+       if (ret)
+               goto do_unlock;
+       ret = gfs2_meta_inode_buffer(ip, &bh);
+       if (ret == 0) {
+               di = (struct gfs2_dinode *)bh->b_data;
+               atime.tv_sec = be64_to_cpu(di->di_atime);
+               atime.tv_nsec = be32_to_cpu(di->di_atime_nsec);
+               if (timespec_compare(&inode->i_atime, &atime) > 0) {
+                       gfs2_trans_add_bh(ip->i_gl, bh, 1);
+                       gfs2_dinode_out(ip, bh->b_data);
+               }
+               brelse(bh);
        }
+       gfs2_trans_end(sdp);
+do_unlock:
+       gfs2_glock_dq_uninit(&gh);
+do_flush:
+       if (sync != 0)
+               gfs2_log_flush(GFS2_SB(inode), ip->i_gl);
+       return ret;
+}
 
-       return 0;
+/**
+ * gfs2_make_fs_ro - Turn a Read-Write FS into a Read-Only one
+ * @sdp: the filesystem
+ *
+ * Returns: errno
+ */
+
+static int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
+{
+       struct gfs2_holder t_gh;
+       int error;
+
+       gfs2_quota_sync(sdp);
+       gfs2_statfs_sync(sdp);
+
+       error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, GL_NOCACHE,
+                                  &t_gh);
+       if (error && !test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
+               return error;
+
+       gfs2_meta_syncfs(sdp);
+       gfs2_log_shutdown(sdp);
+
+       clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
+
+       if (t_gh.gh_gl)
+               gfs2_glock_dq_uninit(&t_gh);
+
+       gfs2_quota_cleanup(sdp);
+
+       return error;
 }
 
 /**
@@ -73,12 +133,6 @@ static void gfs2_put_super(struct super_block *sb)
        struct gfs2_sbd *sdp = sb->s_fs_info;
        int error;
 
-       if (!sdp)
-               return;
-
-       if (!strncmp(sb->s_type->name, "gfs2meta", 8))
-               return; /* Nothing to do */
-
        /*  Unfreeze the filesystem, if we need to  */
 
        mutex_lock(&sdp->sd_freeze_lock);
@@ -101,7 +155,6 @@ static void gfs2_put_super(struct super_block *sb)
 
        /*  Release stuff  */
 
-       iput(sdp->sd_master_dir);
        iput(sdp->sd_jindex);
        iput(sdp->sd_inum_inode);
        iput(sdp->sd_statfs_inode);
@@ -152,6 +205,7 @@ static void gfs2_write_super(struct super_block *sb)
  *
  * Flushes the log to disk.
  */
+
 static int gfs2_sync_fs(struct super_block *sb, int wait)
 {
        sb->s_dirt = 0;
@@ -270,14 +324,6 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data)
                }
        }
 
-       if (*flags & (MS_NOATIME | MS_NODIRATIME))
-               set_bit(SDF_NOATIME, &sdp->sd_flags);
-       else
-               clear_bit(SDF_NOATIME, &sdp->sd_flags);
-
-       /* Don't let the VFS update atimes.  GFS2 handles this itself. */
-       *flags |= MS_NOATIME | MS_NODIRATIME;
-
        return error;
 }
 
@@ -295,6 +341,7 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data)
  * inode's blocks, or alternatively pass the baton on to another
  * node for later deallocation.
  */
+
 static void gfs2_drop_inode(struct inode *inode)
 {
        struct gfs2_inode *ip = GFS2_I(inode);
@@ -333,6 +380,16 @@ static void gfs2_clear_inode(struct inode *inode)
        }
 }
 
+static int is_ancestor(const struct dentry *d1, const struct dentry *d2)
+{
+       do {
+               if (d1 == d2)
+                       return 1;
+               d1 = d1->d_parent;
+       } while (!IS_ROOT(d1));
+       return 0;
+}
+
 /**
  * gfs2_show_options - Show mount options for /proc/mounts
  * @s: seq_file structure
@@ -346,6 +403,8 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
        struct gfs2_sbd *sdp = mnt->mnt_sb->s_fs_info;
        struct gfs2_args *args = &sdp->sd_args;
 
+       if (is_ancestor(mnt->mnt_root, sdp->sd_master_dir))
+               seq_printf(s, ",meta");
        if (args->ar_lockproto[0])
                seq_printf(s, ",lockproto=%s", args->ar_lockproto);
        if (args->ar_locktable[0])
@@ -414,6 +473,7 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
  * conversion on the iopen lock, but we can change that later. This
  * is safe, just less efficient.
  */
+
 static void gfs2_delete_inode(struct inode *inode)
 {
        struct gfs2_sbd *sdp = inode->i_sb->s_fs_info;
@@ -478,8 +538,6 @@ out:
        clear_inode(inode);
 }
 
-
-
 static struct inode *gfs2_alloc_inode(struct super_block *sb)
 {
        struct gfs2_inode *ip;
index ca831991cbc2d8a9cd0e82ee1ec6dc8f839d2d13..c3ba3d9d0aac3ca4fa94f906691247e4816c6fbc 100644 (file)
 #include "trans.h"
 #include "util.h"
 
-static const u32 gfs2_old_fs_formats[] = {
-        0
-};
-
-static const u32 gfs2_old_multihost_formats[] = {
-        0
-};
-
-/**
- * gfs2_tune_init - Fill a gfs2_tune structure with default values
- * @gt: tune
- *
- */
-
-void gfs2_tune_init(struct gfs2_tune *gt)
-{
-       spin_lock_init(&gt->gt_spin);
-
-       gt->gt_demote_secs = 300;
-       gt->gt_incore_log_blocks = 1024;
-       gt->gt_log_flush_secs = 60;
-       gt->gt_recoverd_secs = 60;
-       gt->gt_logd_secs = 1;
-       gt->gt_quotad_secs = 5;
-       gt->gt_quota_simul_sync = 64;
-       gt->gt_quota_warn_period = 10;
-       gt->gt_quota_scale_num = 1;
-       gt->gt_quota_scale_den = 1;
-       gt->gt_quota_cache_secs = 300;
-       gt->gt_quota_quantum = 60;
-       gt->gt_atime_quantum = 3600;
-       gt->gt_new_files_jdata = 0;
-       gt->gt_max_readahead = 1 << 18;
-       gt->gt_stall_secs = 600;
-       gt->gt_complain_secs = 10;
-       gt->gt_statfs_quantum = 30;
-       gt->gt_statfs_slow = 0;
-}
-
-/**
- * gfs2_check_sb - Check superblock
- * @sdp: the filesystem
- * @sb: The superblock
- * @silent: Don't print a message if the check fails
- *
- * Checks the version code of the FS is one that we understand how to
- * read and that the sizes of the various on-disk structures have not
- * changed.
- */
-
-int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb_host *sb, int silent)
-{
-       unsigned int x;
-
-       if (sb->sb_magic != GFS2_MAGIC ||
-           sb->sb_type != GFS2_METATYPE_SB) {
-               if (!silent)
-                       printk(KERN_WARNING "GFS2: not a GFS2 filesystem\n");
-               return -EINVAL;
-       }
-
-       /*  If format numbers match exactly, we're done.  */
-
-       if (sb->sb_fs_format == GFS2_FORMAT_FS &&
-           sb->sb_multihost_format == GFS2_FORMAT_MULTI)
-               return 0;
-
-       if (sb->sb_fs_format != GFS2_FORMAT_FS) {
-               for (x = 0; gfs2_old_fs_formats[x]; x++)
-                       if (gfs2_old_fs_formats[x] == sb->sb_fs_format)
-                               break;
-
-               if (!gfs2_old_fs_formats[x]) {
-                       printk(KERN_WARNING
-                              "GFS2: code version (%u, %u) is incompatible "
-                              "with ondisk format (%u, %u)\n",
-                              GFS2_FORMAT_FS, GFS2_FORMAT_MULTI,
-                              sb->sb_fs_format, sb->sb_multihost_format);
-                       printk(KERN_WARNING
-                              "GFS2: I don't know how to upgrade this FS\n");
-                       return -EINVAL;
-               }
-       }
-
-       if (sb->sb_multihost_format != GFS2_FORMAT_MULTI) {
-               for (x = 0; gfs2_old_multihost_formats[x]; x++)
-                       if (gfs2_old_multihost_formats[x] ==
-                           sb->sb_multihost_format)
-                               break;
-
-               if (!gfs2_old_multihost_formats[x]) {
-                       printk(KERN_WARNING
-                              "GFS2: code version (%u, %u) is incompatible "
-                              "with ondisk format (%u, %u)\n",
-                              GFS2_FORMAT_FS, GFS2_FORMAT_MULTI,
-                              sb->sb_fs_format, sb->sb_multihost_format);
-                       printk(KERN_WARNING
-                              "GFS2: I don't know how to upgrade this FS\n");
-                       return -EINVAL;
-               }
-       }
-
-       if (!sdp->sd_args.ar_upgrade) {
-               printk(KERN_WARNING
-                      "GFS2: code version (%u, %u) is incompatible "
-                      "with ondisk format (%u, %u)\n",
-                      GFS2_FORMAT_FS, GFS2_FORMAT_MULTI,
-                      sb->sb_fs_format, sb->sb_multihost_format);
-               printk(KERN_INFO
-                      "GFS2: Use the \"upgrade\" mount option to upgrade "
-                      "the FS\n");
-               printk(KERN_INFO "GFS2: See the manual for more details\n");
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-
-static void end_bio_io_page(struct bio *bio, int error)
-{
-       struct page *page = bio->bi_private;
-
-       if (!error)
-               SetPageUptodate(page);
-       else
-               printk(KERN_WARNING "gfs2: error %d reading superblock\n", error);
-       unlock_page(page);
-}
-
-static void gfs2_sb_in(struct gfs2_sb_host *sb, const void *buf)
-{
-       const struct gfs2_sb *str = buf;
-
-       sb->sb_magic = be32_to_cpu(str->sb_header.mh_magic);
-       sb->sb_type = be32_to_cpu(str->sb_header.mh_type);
-       sb->sb_format = be32_to_cpu(str->sb_header.mh_format);
-       sb->sb_fs_format = be32_to_cpu(str->sb_fs_format);
-       sb->sb_multihost_format = be32_to_cpu(str->sb_multihost_format);
-       sb->sb_bsize = be32_to_cpu(str->sb_bsize);
-       sb->sb_bsize_shift = be32_to_cpu(str->sb_bsize_shift);
-       sb->sb_master_dir.no_addr = be64_to_cpu(str->sb_master_dir.no_addr);
-       sb->sb_master_dir.no_formal_ino = be64_to_cpu(str->sb_master_dir.no_formal_ino);
-       sb->sb_root_dir.no_addr = be64_to_cpu(str->sb_root_dir.no_addr);
-       sb->sb_root_dir.no_formal_ino = be64_to_cpu(str->sb_root_dir.no_formal_ino);
-
-       memcpy(sb->sb_lockproto, str->sb_lockproto, GFS2_LOCKNAME_LEN);
-       memcpy(sb->sb_locktable, str->sb_locktable, GFS2_LOCKNAME_LEN);
-}
-
-/**
- * gfs2_read_super - Read the gfs2 super block from disk
- * @sdp: The GFS2 super block
- * @sector: The location of the super block
- * @error: The error code to return
- *
- * This uses the bio functions to read the super block from disk
- * because we want to be 100% sure that we never read cached data.
- * A super block is read twice only during each GFS2 mount and is
- * never written to by the filesystem. The first time its read no
- * locks are held, and the only details which are looked at are those
- * relating to the locking protocol. Once locking is up and working,
- * the sb is read again under the lock to establish the location of
- * the master directory (contains pointers to journals etc) and the
- * root directory.
- *
- * Returns: 0 on success or error
- */
-
-int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector)
-{
-       struct super_block *sb = sdp->sd_vfs;
-       struct gfs2_sb *p;
-       struct page *page;
-       struct bio *bio;
-
-       page = alloc_page(GFP_NOFS);
-       if (unlikely(!page))
-               return -ENOBUFS;
-
-       ClearPageUptodate(page);
-       ClearPageDirty(page);
-       lock_page(page);
-
-       bio = bio_alloc(GFP_NOFS, 1);
-       if (unlikely(!bio)) {
-               __free_page(page);
-               return -ENOBUFS;
-       }
-
-       bio->bi_sector = sector * (sb->s_blocksize >> 9);
-       bio->bi_bdev = sb->s_bdev;
-       bio_add_page(bio, page, PAGE_SIZE, 0);
-
-       bio->bi_end_io = end_bio_io_page;
-       bio->bi_private = page;
-       submit_bio(READ_SYNC | (1 << BIO_RW_META), bio);
-       wait_on_page_locked(page);
-       bio_put(bio);
-       if (!PageUptodate(page)) {
-               __free_page(page);
-               return -EIO;
-       }
-       p = kmap(page);
-       gfs2_sb_in(&sdp->sd_sb, p);
-       kunmap(page);
-       __free_page(page);
-       return 0;
-}
-
-/**
- * gfs2_read_sb - Read super block
- * @sdp: The GFS2 superblock
- * @gl: the glock for the superblock (assumed to be held)
- * @silent: Don't print message if mount fails
- *
- */
-
-int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent)
-{
-       u32 hash_blocks, ind_blocks, leaf_blocks;
-       u32 tmp_blocks;
-       unsigned int x;
-       int error;
-
-       error = gfs2_read_super(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift);
-       if (error) {
-               if (!silent)
-                       fs_err(sdp, "can't read superblock\n");
-               return error;
-       }
-
-       error = gfs2_check_sb(sdp, &sdp->sd_sb, silent);
-       if (error)
-               return error;
-
-       sdp->sd_fsb2bb_shift = sdp->sd_sb.sb_bsize_shift -
-                              GFS2_BASIC_BLOCK_SHIFT;
-       sdp->sd_fsb2bb = 1 << sdp->sd_fsb2bb_shift;
-       sdp->sd_diptrs = (sdp->sd_sb.sb_bsize -
-                         sizeof(struct gfs2_dinode)) / sizeof(u64);
-       sdp->sd_inptrs = (sdp->sd_sb.sb_bsize -
-                         sizeof(struct gfs2_meta_header)) / sizeof(u64);
-       sdp->sd_jbsize = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header);
-       sdp->sd_hash_bsize = sdp->sd_sb.sb_bsize / 2;
-       sdp->sd_hash_bsize_shift = sdp->sd_sb.sb_bsize_shift - 1;
-       sdp->sd_hash_ptrs = sdp->sd_hash_bsize / sizeof(u64);
-       sdp->sd_qc_per_block = (sdp->sd_sb.sb_bsize -
-                               sizeof(struct gfs2_meta_header)) /
-                               sizeof(struct gfs2_quota_change);
-
-       /* Compute maximum reservation required to add a entry to a directory */
-
-       hash_blocks = DIV_ROUND_UP(sizeof(u64) * (1 << GFS2_DIR_MAX_DEPTH),
-                            sdp->sd_jbsize);
-
-       ind_blocks = 0;
-       for (tmp_blocks = hash_blocks; tmp_blocks > sdp->sd_diptrs;) {
-               tmp_blocks = DIV_ROUND_UP(tmp_blocks, sdp->sd_inptrs);
-               ind_blocks += tmp_blocks;
-       }
-
-       leaf_blocks = 2 + GFS2_DIR_MAX_DEPTH;
-
-       sdp->sd_max_dirres = hash_blocks + ind_blocks + leaf_blocks;
-
-       sdp->sd_heightsize[0] = sdp->sd_sb.sb_bsize -
-                               sizeof(struct gfs2_dinode);
-       sdp->sd_heightsize[1] = sdp->sd_sb.sb_bsize * sdp->sd_diptrs;
-       for (x = 2;; x++) {
-               u64 space, d;
-               u32 m;
-
-               space = sdp->sd_heightsize[x - 1] * sdp->sd_inptrs;
-               d = space;
-               m = do_div(d, sdp->sd_inptrs);
-
-               if (d != sdp->sd_heightsize[x - 1] || m)
-                       break;
-               sdp->sd_heightsize[x] = space;
-       }
-       sdp->sd_max_height = x;
-       sdp->sd_heightsize[x] = ~0;
-       gfs2_assert(sdp, sdp->sd_max_height <= GFS2_MAX_META_HEIGHT);
-
-       sdp->sd_jheightsize[0] = sdp->sd_sb.sb_bsize -
-                                sizeof(struct gfs2_dinode);
-       sdp->sd_jheightsize[1] = sdp->sd_jbsize * sdp->sd_diptrs;
-       for (x = 2;; x++) {
-               u64 space, d;
-               u32 m;
-
-               space = sdp->sd_jheightsize[x - 1] * sdp->sd_inptrs;
-               d = space;
-               m = do_div(d, sdp->sd_inptrs);
-
-               if (d != sdp->sd_jheightsize[x - 1] || m)
-                       break;
-               sdp->sd_jheightsize[x] = space;
-       }
-       sdp->sd_max_jheight = x;
-       sdp->sd_jheightsize[x] = ~0;
-       gfs2_assert(sdp, sdp->sd_max_jheight <= GFS2_MAX_META_HEIGHT);
-
-       return 0;
-}
-
 /**
  * gfs2_jindex_hold - Grab a lock on the jindex
  * @sdp: The GFS2 superblock
@@ -581,39 +274,6 @@ fail:
        return error;
 }
 
-/**
- * gfs2_make_fs_ro - Turn a Read-Write FS into a Read-Only one
- * @sdp: the filesystem
- *
- * Returns: errno
- */
-
-int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
-{
-       struct gfs2_holder t_gh;
-       int error;
-
-       gfs2_quota_sync(sdp);
-       gfs2_statfs_sync(sdp);
-
-       error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, GL_NOCACHE,
-                                  &t_gh);
-       if (error && !test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
-               return error;
-
-       gfs2_meta_syncfs(sdp);
-       gfs2_log_shutdown(sdp);
-
-       clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
-
-       if (t_gh.gh_gl)
-               gfs2_glock_dq_uninit(&t_gh);
-
-       gfs2_quota_cleanup(sdp);
-
-       return error;
-}
-
 static void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc, const void *buf)
 {
        const struct gfs2_statfs_change *str = buf;
index 44361ecc44f77fa1771a7cb48b08cdb1a436cdc4..50a4c9b1215ebecae8e694c26ea05c0303b712dd 100644 (file)
 
 #include "incore.h"
 
-void gfs2_tune_init(struct gfs2_tune *gt);
-
-int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb_host *sb, int silent);
-int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent);
-int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector);
 void gfs2_lm_unmount(struct gfs2_sbd *sdp);
 
 static inline unsigned int gfs2_jindex_size(struct gfs2_sbd *sdp)
@@ -40,7 +35,6 @@ int gfs2_lookup_in_master_dir(struct gfs2_sbd *sdp, char *filename,
                              struct gfs2_inode **ipp);
 
 int gfs2_make_fs_rw(struct gfs2_sbd *sdp);
-int gfs2_make_fs_ro(struct gfs2_sbd *sdp);
 
 int gfs2_statfs_init(struct gfs2_sbd *sdp);
 void gfs2_statfs_change(struct gfs2_sbd *sdp,
index 74846559fc3f4adc6a2ca913ff44a1ec7138d064..7e1879f1a02c6e16d83b3d611902f665dc3149b2 100644 (file)
@@ -269,14 +269,6 @@ ARGS_ATTR(quota,           "%u\n");
 ARGS_ATTR(suiddir,         "%d\n");
 ARGS_ATTR(data,            "%d\n");
 
-/* one oddball doesn't fit the macro mold */
-static ssize_t noatime_show(struct gfs2_sbd *sdp, char *buf)
-{
-       return snprintf(buf, PAGE_SIZE, "%d\n",
-                       !!test_bit(SDF_NOATIME, &sdp->sd_flags));
-}
-static struct args_attr args_attr_noatime = __ATTR_RO(noatime);
-
 static struct attribute *args_attrs[] = {
        &args_attr_lockproto.attr,
        &args_attr_locktable.attr,
@@ -292,7 +284,6 @@ static struct attribute *args_attrs[] = {
        &args_attr_quota.attr,
        &args_attr_suiddir.attr,
        &args_attr_data.attr,
-       &args_attr_noatime.attr,
        NULL,
 };
 
@@ -407,7 +398,6 @@ TUNE_ATTR(incore_log_blocks, 0);
 TUNE_ATTR(log_flush_secs, 0);
 TUNE_ATTR(quota_warn_period, 0);
 TUNE_ATTR(quota_quantum, 0);
-TUNE_ATTR(atime_quantum, 0);
 TUNE_ATTR(max_readahead, 0);
 TUNE_ATTR(complain_secs, 0);
 TUNE_ATTR(statfs_slow, 0);
@@ -427,7 +417,6 @@ static struct attribute *tune_attrs[] = {
        &tune_attr_log_flush_secs.attr,
        &tune_attr_quota_warn_period.attr,
        &tune_attr_quota_quantum.attr,
-       &tune_attr_atime_quantum.attr,
        &tune_attr_max_readahead.attr,
        &tune_attr_complain_secs.attr,
        &tune_attr_statfs_slow.attr,
index ecc3330972e5a2de1ca8e397e3a9a0d90aec2ce8..7408227c49c91cefed99f861a90a8bbb85e8b346 100644 (file)
@@ -120,22 +120,21 @@ static int (*check_part[])(struct parsed_partitions *, struct block_device *) =
  * a pointer to that same buffer (for convenience).
  */
 
-char *disk_name(struct gendisk *hd, int part, char *buf)
+char *disk_name(struct gendisk *hd, int partno, char *buf)
 {
-       if (!part)
+       if (!partno)
                snprintf(buf, BDEVNAME_SIZE, "%s", hd->disk_name);
        else if (isdigit(hd->disk_name[strlen(hd->disk_name)-1]))
-               snprintf(buf, BDEVNAME_SIZE, "%sp%d", hd->disk_name, part);
+               snprintf(buf, BDEVNAME_SIZE, "%sp%d", hd->disk_name, partno);
        else
-               snprintf(buf, BDEVNAME_SIZE, "%s%d", hd->disk_name, part);
+               snprintf(buf, BDEVNAME_SIZE, "%s%d", hd->disk_name, partno);
 
        return buf;
 }
 
 const char *bdevname(struct block_device *bdev, char *buf)
 {
-       int part = MINOR(bdev->bd_dev) - bdev->bd_disk->first_minor;
-       return disk_name(bdev->bd_disk, part, buf);
+       return disk_name(bdev->bd_disk, bdev->bd_part->partno, buf);
 }
 
 EXPORT_SYMBOL(bdevname);
@@ -169,7 +168,7 @@ check_partition(struct gendisk *hd, struct block_device *bdev)
        if (isdigit(state->name[strlen(state->name)-1]))
                sprintf(state->name, "p");
 
-       state->limit = hd->minors;
+       state->limit = disk_max_parts(hd);
        i = res = err = 0;
        while (!res && check_part[i]) {
                memset(&state->parts, 0, sizeof(state->parts));
@@ -204,21 +203,22 @@ static ssize_t part_start_show(struct device *dev,
        return sprintf(buf, "%llu\n",(unsigned long long)p->start_sect);
 }
 
-static ssize_t part_size_show(struct device *dev,
-                             struct device_attribute *attr, char *buf)
+ssize_t part_size_show(struct device *dev,
+                      struct device_attribute *attr, char *buf)
 {
        struct hd_struct *p = dev_to_part(dev);
        return sprintf(buf, "%llu\n",(unsigned long long)p->nr_sects);
 }
 
-static ssize_t part_stat_show(struct device *dev,
-                             struct device_attribute *attr, char *buf)
+ssize_t part_stat_show(struct device *dev,
+                      struct device_attribute *attr, char *buf)
 {
        struct hd_struct *p = dev_to_part(dev);
+       int cpu;
 
-       preempt_disable();
-       part_round_stats(p);
-       preempt_enable();
+       cpu = part_stat_lock();
+       part_round_stats(cpu, p);
+       part_stat_unlock();
        return sprintf(buf,
                "%8lu %8lu %8llu %8u "
                "%8lu %8lu %8llu %8u "
@@ -238,17 +238,17 @@ static ssize_t part_stat_show(struct device *dev,
 }
 
 #ifdef CONFIG_FAIL_MAKE_REQUEST
-static ssize_t part_fail_show(struct device *dev,
-                             struct device_attribute *attr, char *buf)
+ssize_t part_fail_show(struct device *dev,
+                      struct device_attribute *attr, char *buf)
 {
        struct hd_struct *p = dev_to_part(dev);
 
        return sprintf(buf, "%d\n", p->make_it_fail);
 }
 
-static ssize_t part_fail_store(struct device *dev,
-                              struct device_attribute *attr,
-                              const char *buf, size_t count)
+ssize_t part_fail_store(struct device *dev,
+                       struct device_attribute *attr,
+                       const char *buf, size_t count)
 {
        struct hd_struct *p = dev_to_part(dev);
        int i;
@@ -300,40 +300,34 @@ struct device_type part_type = {
        .release        = part_release,
 };
 
-static inline void partition_sysfs_add_subdir(struct hd_struct *p)
-{
-       struct kobject *k;
-
-       k = kobject_get(&p->dev.kobj);
-       p->holder_dir = kobject_create_and_add("holders", k);
-       kobject_put(k);
-}
-
-static inline void disk_sysfs_add_subdirs(struct gendisk *disk)
+static void delete_partition_rcu_cb(struct rcu_head *head)
 {
-       struct kobject *k;
+       struct hd_struct *part = container_of(head, struct hd_struct, rcu_head);
 
-       k = kobject_get(&disk->dev.kobj);
-       disk->holder_dir = kobject_create_and_add("holders", k);
-       disk->slave_dir = kobject_create_and_add("slaves", k);
-       kobject_put(k);
+       part->start_sect = 0;
+       part->nr_sects = 0;
+       part_stat_set_all(part, 0);
+       put_device(part_to_dev(part));
 }
 
-void delete_partition(struct gendisk *disk, int part)
+void delete_partition(struct gendisk *disk, int partno)
 {
-       struct hd_struct *p = disk->part[part-1];
+       struct disk_part_tbl *ptbl = disk->part_tbl;
+       struct hd_struct *part;
 
-       if (!p)
+       if (partno >= ptbl->len)
                return;
-       if (!p->nr_sects)
+
+       part = ptbl->part[partno];
+       if (!part)
                return;
-       disk->part[part-1] = NULL;
-       p->start_sect = 0;
-       p->nr_sects = 0;
-       part_stat_set_all(p, 0);
-       kobject_put(p->holder_dir);
-       device_del(&p->dev);
-       put_device(&p->dev);
+
+       blk_free_devt(part_devt(part));
+       rcu_assign_pointer(ptbl->part[partno], NULL);
+       kobject_put(part->holder_dir);
+       device_del(part_to_dev(part));
+
+       call_rcu(&part->rcu_head, delete_partition_rcu_cb);
 }
 
 static ssize_t whole_disk_show(struct device *dev,
@@ -344,102 +338,132 @@ static ssize_t whole_disk_show(struct device *dev,
 static DEVICE_ATTR(whole_disk, S_IRUSR | S_IRGRP | S_IROTH,
                   whole_disk_show, NULL);
 
-int add_partition(struct gendisk *disk, int part, sector_t start, sector_t len, int flags)
+int add_partition(struct gendisk *disk, int partno,
+                 sector_t start, sector_t len, int flags)
 {
        struct hd_struct *p;
+       dev_t devt = MKDEV(0, 0);
+       struct device *ddev = disk_to_dev(disk);
+       struct device *pdev;
+       struct disk_part_tbl *ptbl;
+       const char *dname;
        int err;
 
+       err = disk_expand_part_tbl(disk, partno);
+       if (err)
+               return err;
+       ptbl = disk->part_tbl;
+
+       if (ptbl->part[partno])
+               return -EBUSY;
+
        p = kzalloc(sizeof(*p), GFP_KERNEL);
        if (!p)
                return -ENOMEM;
 
        if (!init_part_stats(p)) {
                err = -ENOMEM;
-               goto out0;
+               goto out_free;
        }
+       pdev = part_to_dev(p);
+
        p->start_sect = start;
        p->nr_sects = len;
-       p->partno = part;
-       p->policy = disk->policy;
+       p->partno = partno;
+       p->policy = get_disk_ro(disk);
 
-       if (isdigit(disk->dev.bus_id[strlen(disk->dev.bus_id)-1]))
-               snprintf(p->dev.bus_id, BUS_ID_SIZE,
-               "%sp%d", disk->dev.bus_id, part);
+       dname = dev_name(ddev);
+       if (isdigit(dname[strlen(dname) - 1]))
+               snprintf(pdev->bus_id, BUS_ID_SIZE, "%sp%d", dname, partno);
        else
-               snprintf(p->dev.bus_id, BUS_ID_SIZE,
-                        "%s%d", disk->dev.bus_id, part);
+               snprintf(pdev->bus_id, BUS_ID_SIZE, "%s%d", dname, partno);
 
-       device_initialize(&p->dev);
-       p->dev.devt = MKDEV(disk->major, disk->first_minor + part);
-       p->dev.class = &block_class;
-       p->dev.type = &part_type;
-       p->dev.parent = &disk->dev;
-       disk->part[part-1] = p;
+       device_initialize(pdev);
+       pdev->class = &block_class;
+       pdev->type = &part_type;
+       pdev->parent = ddev;
+
+       err = blk_alloc_devt(p, &devt);
+       if (err)
+               goto out_free;
+       pdev->devt = devt;
 
        /* delay uevent until 'holders' subdir is created */
-       p->dev.uevent_suppress = 1;
-       err = device_add(&p->dev);
+       pdev->uevent_suppress = 1;
+       err = device_add(pdev);
        if (err)
-               goto out1;
-       partition_sysfs_add_subdir(p);
-       p->dev.uevent_suppress = 0;
+               goto out_put;
+
+       err = -ENOMEM;
+       p->holder_dir = kobject_create_and_add("holders", &pdev->kobj);
+       if (!p->holder_dir)
+               goto out_del;
+
+       pdev->uevent_suppress = 0;
        if (flags & ADDPART_FLAG_WHOLEDISK) {
-               err = device_create_file(&p->dev, &dev_attr_whole_disk);
+               err = device_create_file(pdev, &dev_attr_whole_disk);
                if (err)
-                       goto out2;
+                       goto out_del;
        }
 
+       /* everything is up and running, commence */
+       INIT_RCU_HEAD(&p->rcu_head);
+       rcu_assign_pointer(ptbl->part[partno], p);
+
        /* suppress uevent if the disk supresses it */
-       if (!disk->dev.uevent_suppress)
-               kobject_uevent(&p->dev.kobj, KOBJ_ADD);
+       if (!ddev->uevent_suppress)
+               kobject_uevent(&pdev->kobj, KOBJ_ADD);
 
        return 0;
 
-out2:
-       device_del(&p->dev);
-out1:
-       put_device(&p->dev);
-       free_part_stats(p);
-out0:
+out_free:
        kfree(p);
        return err;
+out_del:
+       kobject_put(p->holder_dir);
+       device_del(pdev);
+out_put:
+       put_device(pdev);
+       blk_free_devt(devt);
+       return err;
 }
 
 /* Not exported, helper to add_disk(). */
 void register_disk(struct gendisk *disk)
 {
+       struct device *ddev = disk_to_dev(disk);
        struct block_device *bdev;
+       struct disk_part_iter piter;
+       struct hd_struct *part;
        char *s;
-       int i;
-       struct hd_struct *p;
        int err;
 
-       disk->dev.parent = disk->driverfs_dev;
-       disk->dev.devt = MKDEV(disk->major, disk->first_minor);
+       ddev->parent = disk->driverfs_dev;
 
-       strlcpy(disk->dev.bus_id, disk->disk_name, BUS_ID_SIZE);
+       strlcpy(ddev->bus_id, disk->disk_name, BUS_ID_SIZE);
        /* ewww... some of these buggers have / in the name... */
-       s = strchr(disk->dev.bus_id, '/');
+       s = strchr(ddev->bus_id, '/');
        if (s)
                *s = '!';
 
        /* delay uevents, until we scanned partition table */
-       disk->dev.uevent_suppress = 1;
+       ddev->uevent_suppress = 1;
 
-       if (device_add(&disk->dev))
+       if (device_add(ddev))
                return;
 #ifndef CONFIG_SYSFS_DEPRECATED
-       err = sysfs_create_link(block_depr, &disk->dev.kobj,
-                               kobject_name(&disk->dev.kobj));
+       err = sysfs_create_link(block_depr, &ddev->kobj,
+                               kobject_name(&ddev->kobj));
        if (err) {
-               device_del(&disk->dev);
+               device_del(ddev);
                return;
        }
 #endif
-       disk_sysfs_add_subdirs(disk);
+       disk->part0.holder_dir = kobject_create_and_add("holders", &ddev->kobj);
+       disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj);
 
        /* No minors to use for partitions */
-       if (disk->minors == 1)
+       if (!disk_partitionable(disk))
                goto exit;
 
        /* No such device (e.g., media were just removed) */
@@ -458,41 +482,57 @@ void register_disk(struct gendisk *disk)
 
 exit:
        /* announce disk after possible partitions are created */
-       disk->dev.uevent_suppress = 0;
-       kobject_uevent(&disk->dev.kobj, KOBJ_ADD);
+       ddev->uevent_suppress = 0;
+       kobject_uevent(&ddev->kobj, KOBJ_ADD);
 
        /* announce possible partitions */
-       for (i = 1; i < disk->minors; i++) {
-               p = disk->part[i-1];
-               if (!p || !p->nr_sects)
-                       continue;
-               kobject_uevent(&p->dev.kobj, KOBJ_ADD);
-       }
+       disk_part_iter_init(&piter, disk, 0);
+       while ((part = disk_part_iter_next(&piter)))
+               kobject_uevent(&part_to_dev(part)->kobj, KOBJ_ADD);
+       disk_part_iter_exit(&piter);
 }
 
 int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
 {
+       struct disk_part_iter piter;
+       struct hd_struct *part;
        struct parsed_partitions *state;
-       int p, res;
+       int p, highest, res;
 
        if (bdev->bd_part_count)
                return -EBUSY;
        res = invalidate_partition(disk, 0);
        if (res)
                return res;
-       bdev->bd_invalidated = 0;
-       for (p = 1; p < disk->minors; p++)
-               delete_partition(disk, p);
+
+       disk_part_iter_init(&piter, disk, DISK_PITER_INCL_EMPTY);
+       while ((part = disk_part_iter_next(&piter)))
+               delete_partition(disk, part->partno);
+       disk_part_iter_exit(&piter);
+
        if (disk->fops->revalidate_disk)
                disk->fops->revalidate_disk(disk);
+       check_disk_size_change(disk, bdev);
+       bdev->bd_invalidated = 0;
        if (!get_capacity(disk) || !(state = check_partition(disk, bdev)))
                return 0;
        if (IS_ERR(state))      /* I/O error reading the partition table */
                return -EIO;
 
        /* tell userspace that the media / partition table may have changed */
-       kobject_uevent(&disk->dev.kobj, KOBJ_CHANGE);
+       kobject_uevent(&disk_to_dev(disk)->kobj, KOBJ_CHANGE);
 
+       /* Detect the highest partition number and preallocate
+        * disk->part_tbl.  This is an optimization and not strictly
+        * necessary.
+        */
+       for (p = 1, highest = 0; p < state->limit; p++)
+               if (state->parts[p].size)
+                       highest = p;
+
+       disk_expand_part_tbl(disk, highest);
+
+       /* add partitions */
        for (p = 1; p < state->limit; p++) {
                sector_t size = state->parts[p].size;
                sector_t from = state->parts[p].from;
@@ -541,25 +581,31 @@ EXPORT_SYMBOL(read_dev_sector);
 
 void del_gendisk(struct gendisk *disk)
 {
-       int p;
+       struct disk_part_iter piter;
+       struct hd_struct *part;
 
        /* invalidate stuff */
-       for (p = disk->minors - 1; p > 0; p--) {
-               invalidate_partition(disk, p);
-               delete_partition(disk, p);
+       disk_part_iter_init(&piter, disk,
+                            DISK_PITER_INCL_EMPTY | DISK_PITER_REVERSE);
+       while ((part = disk_part_iter_next(&piter))) {
+               invalidate_partition(disk, part->partno);
+               delete_partition(disk, part->partno);
        }
+       disk_part_iter_exit(&piter);
+
        invalidate_partition(disk, 0);
-       disk->capacity = 0;
+       blk_free_devt(disk_to_dev(disk)->devt);
+       set_capacity(disk, 0);
        disk->flags &= ~GENHD_FL_UP;
        unlink_gendisk(disk);
-       disk_stat_set_all(disk, 0);
-       disk->stamp = 0;
+       part_stat_set_all(&disk->part0, 0);
+       disk->part0.stamp = 0;
 
-       kobject_put(disk->holder_dir);
+       kobject_put(disk->part0.holder_dir);
        kobject_put(disk->slave_dir);
        disk->driverfs_dev = NULL;
 #ifndef CONFIG_SYSFS_DEPRECATED
-       sysfs_remove_link(block_depr, disk->dev.bus_id);
+       sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk)));
 #endif
-       device_del(&disk->dev);
+       device_del(disk_to_dev(disk));
 }
index 17ae8ecd9e8b60afae6a8538d850ed7032477a4f..98dbe1a84528c3c73e04774b45409b614e758a67 100644 (file)
@@ -5,15 +5,13 @@
  * add_gd_partition adds a partitions details to the devices partition
  * description.
  */
-enum { MAX_PART = 256 };
-
 struct parsed_partitions {
        char name[BDEVNAME_SIZE];
        struct {
                sector_t from;
                sector_t size;
                int flags;
-       } parts[MAX_PART];
+       } parts[DISK_MAX_PARTS];
        int next;
        int limit;
 };
index 1bbc6f4bb09cb850cec29e64ea34bfabe083bb3b..a1e701c27156f78201532e8f701d1af2266744f0 100644 (file)
@@ -898,6 +898,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
        if (unlikely(!(out->f_mode & FMODE_WRITE)))
                return -EBADF;
 
+       if (unlikely(out->f_flags & O_APPEND))
+               return -EINVAL;
+
        ret = rw_verify_area(WRITE, out, ppos, len);
        if (unlikely(ret < 0))
                return ret;
index 986061ae1b9b18f1e22220e04b0db715a79c3dd6..36d5fcd3f593d8694926e70181b1bade9a1df8b6 100644 (file)
@@ -1001,12 +1001,13 @@ xfs_buf_iodone_work(
         * We can get an EOPNOTSUPP to ordered writes.  Here we clear the
         * ordered flag and reissue them.  Because we can't tell the higher
         * layers directly that they should not issue ordered I/O anymore, they
-        * need to check if the ordered flag was cleared during I/O completion.
+        * need to check if the _XFS_BARRIER_FAILED flag was set during I/O completion.
         */
        if ((bp->b_error == EOPNOTSUPP) &&
            (bp->b_flags & (XBF_ORDERED|XBF_ASYNC)) == (XBF_ORDERED|XBF_ASYNC)) {
                XB_TRACE(bp, "ordered_retry", bp->b_iodone);
                bp->b_flags &= ~XBF_ORDERED;
+               bp->b_flags |= _XFS_BARRIER_FAILED;
                xfs_buf_iorequest(bp);
        } else if (bp->b_iodone)
                (*(bp->b_iodone))(bp);
index fe01099566564d0a3dc9cedc850c9874d41bdc6a..456519a088c7bfb5ba472f0a8125818a46a5ac5b 100644 (file)
@@ -85,6 +85,14 @@ typedef enum {
         * modifications being lost.
         */
        _XBF_PAGE_LOCKED = (1 << 22),
+
+       /*
+        * If we try a barrier write, but it fails we have to communicate
+        * this to the upper layers.  Unfortunately b_error gets overwritten
+        * when the buffer is re-issued so we have to add another flag to
+        * keep this information.
+        */
+       _XFS_BARRIER_FAILED = (1 << 23),
 } xfs_buf_flags_t;
 
 typedef enum {
index 503ea89e8b9a24ac1b3da0901191ad82673f50f5..0b02c6443551f78b24af282cad994c5b07a2523f 100644 (file)
@@ -1033,11 +1033,12 @@ xlog_iodone(xfs_buf_t *bp)
        l = iclog->ic_log;
 
        /*
-        * If the ordered flag has been removed by a lower
-        * layer, it means the underlyin device no longer supports
+        * If the _XFS_BARRIER_FAILED flag was set by a lower
+        * layer, it means the underlying device no longer supports
         * barrier I/O. Warn loudly and turn off barriers.
         */
-       if ((l->l_mp->m_flags & XFS_MOUNT_BARRIER) && !XFS_BUF_ISORDERED(bp)) {
+       if (bp->b_flags & _XFS_BARRIER_FAILED) {
+               bp->b_flags &= ~_XFS_BARRIER_FAILED;
                l->l_mp->m_flags &= ~XFS_MOUNT_BARRIER;
                xfs_fs_cmn_err(CE_WARN, l->l_mp,
                                "xlog_iodone: Barriers are no longer supported"
index 714207a1c38795fa40168373ee3858e74bffa607..f5705761a37b14509c5603e79c69292fdb4adb66 100644 (file)
@@ -9,8 +9,8 @@
  * 2 of the Licence, or (at your option) any later version.
  */
 
-#ifndef _ASM_A_OUT_CORE_H
-#define _ASM_A_OUT_CORE_H
+#ifndef ASM_X86__A_OUT_CORE_H
+#define ASM_X86__A_OUT_CORE_H
 
 #ifdef __KERNEL__
 #ifdef CONFIG_X86_32
@@ -70,4 +70,4 @@ static inline void aout_dump_thread(struct pt_regs *regs, struct user *dump)
 
 #endif /* CONFIG_X86_32 */
 #endif /* __KERNEL__ */
-#endif /* _ASM_A_OUT_CORE_H */
+#endif /* ASM_X86__A_OUT_CORE_H */
index 4684f97a5bbd1b1edce881a88e75393b580a2cd1..0948748bc69c1dd8f694c34878551868e01a3da7 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_A_OUT_H
-#define _ASM_X86_A_OUT_H
+#ifndef ASM_X86__A_OUT_H
+#define ASM_X86__A_OUT_H
 
 struct exec
 {
@@ -17,4 +17,4 @@ struct exec
 #define N_DRSIZE(a)    ((a).a_drsize)
 #define N_SYMSIZE(a)   ((a).a_syms)
 
-#endif /* _ASM_X86_A_OUT_H */
+#endif /* ASM_X86__A_OUT_H */
index 35d1743b57ac733502f48c63676f313b8e7f61f3..392e17336be1dede3964b6e61ca4cdf568b258fd 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_ACPI_H
-#define _ASM_X86_ACPI_H
+#ifndef ASM_X86__ACPI_H
+#define ASM_X86__ACPI_H
 
 /*
  *  Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
@@ -175,4 +175,4 @@ static inline void acpi_fake_nodes(const struct bootnode *fake_nodes,
 
 #define acpi_unlazy_tlb(x)     leave_mm(x)
 
-#endif /*__X86_ASM_ACPI_H*/
+#endif /* ASM_X86__ACPI_H */
index e4004a9f6a9a53fa03c7b5ce6db80809180dc703..3617fd4fcdf9faa1f110055cd33f607e98662c76 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_AGP_H
-#define _ASM_X86_AGP_H
+#ifndef ASM_X86__AGP_H
+#define ASM_X86__AGP_H
 
 #include <asm/pgtable.h>
 #include <asm/cacheflush.h>
@@ -32,4 +32,4 @@
 #define free_gatt_pages(table, order)  \
        free_pages((unsigned long)(table), (order))
 
-#endif
+#endif /* ASM_X86__AGP_H */
index f6aa18eadf71717d9e86c53ac3719776fa035969..22d3c9862bf3b3a0967df0c9c2f2b7038d6e1ba3 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_ALTERNATIVE_H
-#define _ASM_X86_ALTERNATIVE_H
+#ifndef ASM_X86__ALTERNATIVE_H
+#define ASM_X86__ALTERNATIVE_H
 
 #include <linux/types.h>
 #include <linux/stddef.h>
@@ -180,4 +180,4 @@ extern void add_nops(void *insns, unsigned int len);
 extern void *text_poke(void *addr, const void *opcode, size_t len);
 extern void *text_poke_early(void *addr, const void *opcode, size_t len);
 
-#endif /* _ASM_X86_ALTERNATIVE_H */
+#endif /* ASM_X86__ALTERNATIVE_H */
index 30a12049353b1bc6c17d9811046f71096b9d6759..783f43e580523e0af5193807b9e670cace005c7d 100644 (file)
@@ -17,8 +17,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
-#ifndef _ASM_X86_AMD_IOMMU_H
-#define _ASM_X86_AMD_IOMMU_H
+#ifndef ASM_X86__AMD_IOMMU_H
+#define ASM_X86__AMD_IOMMU_H
 
 #ifdef CONFIG_AMD_IOMMU
 extern int amd_iommu_init(void);
@@ -29,4 +29,4 @@ static inline int amd_iommu_init(void) { return -ENODEV; }
 static inline void amd_iommu_detect(void) { }
 #endif
 
-#endif
+#endif /* ASM_X86__AMD_IOMMU_H */
index dcc812067394fd5e366810d0d57eb2dbf6f05d70..1ffa4e53c98931b670409c5b226bc23babfc4ef6 100644 (file)
@@ -17,8 +17,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
-#ifndef __AMD_IOMMU_TYPES_H__
-#define __AMD_IOMMU_TYPES_H__
+#ifndef ASM_X86__AMD_IOMMU_TYPES_H
+#define ASM_X86__AMD_IOMMU_TYPES_H
 
 #include <linux/types.h>
 #include <linux/list.h>
@@ -341,4 +341,4 @@ static inline u16 calc_devid(u8 bus, u8 devfn)
        return (((u16)bus) << 8) | devfn;
 }
 
-#endif
+#endif /* ASM_X86__AMD_IOMMU_TYPES_H */
index 133c998161ca4930dae0efe954802a45af2d62d4..65590c9aecd4cfc906f8e643dfc47cb56356ca90 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_APIC_H
-#define _ASM_X86_APIC_H
+#ifndef ASM_X86__APIC_H
+#define ASM_X86__APIC_H
 
 #include <linux/pm.h>
 #include <linux/delay.h>
@@ -54,6 +54,11 @@ extern int disable_apic;
 #endif
 
 extern int is_vsmp_box(void);
+extern void xapic_wait_icr_idle(void);
+extern u32 safe_xapic_wait_icr_idle(void);
+extern u64 xapic_icr_read(void);
+extern void xapic_icr_write(u32, u32);
+extern int setup_profiling_timer(unsigned int);
 
 static inline void native_apic_write(unsigned long reg, u32 v)
 {
@@ -76,9 +81,7 @@ extern int get_physical_broadcast(void);
 static inline void ack_APIC_irq(void)
 {
        /*
-        * ack_APIC_irq() actually gets compiled as a single instruction:
-        * - a single rmw on Pentium/82489DX
-        * - a single write on P6+ cores (CONFIG_X86_GOOD_APIC)
+        * ack_APIC_irq() actually gets compiled as a single instruction
         * ... yummie.
         */
 
@@ -128,4 +131,4 @@ static inline void init_apic_mappings(void) { }
 
 #endif /* !CONFIG_X86_LOCAL_APIC */
 
-#endif /* __ASM_APIC_H */
+#endif /* ASM_X86__APIC_H */
index 6b9008c787319d1040c9520c137a454f24afc06a..c40687da20fc6c9259cd984f2c203480738d11a3 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_APICDEF_H
-#define _ASM_X86_APICDEF_H
+#ifndef ASM_X86__APICDEF_H
+#define ASM_X86__APICDEF_H
 
 /*
  * Constants for various Intel APICs. (local APIC, IOAPIC, etc.)
@@ -411,4 +411,4 @@ struct local_apic {
 #else
  #define BAD_APICID 0xFFFFu
 #endif
-#endif
+#endif /* ASM_X86__APICDEF_H */
index 8411750ceb633763ad2fda66d8f154f9b87cfd7f..72adc3a109cc5258beebbc0aab8b15423a67a10a 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_ARCH_HOOKS_H
-#define _ASM_ARCH_HOOKS_H
+#ifndef ASM_X86__ARCH_HOOKS_H
+#define ASM_X86__ARCH_HOOKS_H
 
 #include <linux/interrupt.h>
 
@@ -25,4 +25,4 @@ extern void pre_time_init_hook(void);
 extern void time_init_hook(void);
 extern void mca_nmi_hook(void);
 
-#endif
+#endif /* ASM_X86__ARCH_HOOKS_H */
index 97220321f39de383b4624533a7ae1969756fb0b6..e1355f44d7c3395753317faaf2b2fb61f100bfea 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_ASM_H
-#define _ASM_X86_ASM_H
+#ifndef ASM_X86__ASM_H
+#define ASM_X86__ASM_H
 
 #ifdef __ASSEMBLY__
 # define __ASM_FORM(x) x
 
 #define _ASM_PTR       __ASM_SEL(.long, .quad)
 #define _ASM_ALIGN     __ASM_SEL(.balign 4, .balign 8)
-#define _ASM_MOV_UL    __ASM_SIZE(mov)
 
+#define _ASM_MOV       __ASM_SIZE(mov)
 #define _ASM_INC       __ASM_SIZE(inc)
 #define _ASM_DEC       __ASM_SIZE(dec)
 #define _ASM_ADD       __ASM_SIZE(add)
 #define _ASM_SUB       __ASM_SIZE(sub)
 #define _ASM_XADD      __ASM_SIZE(xadd)
+
 #define _ASM_AX                __ASM_REG(ax)
 #define _ASM_BX                __ASM_REG(bx)
 #define _ASM_CX                __ASM_REG(cx)
 #define _ASM_DX                __ASM_REG(dx)
+#define _ASM_SP                __ASM_REG(sp)
+#define _ASM_BP                __ASM_REG(bp)
+#define _ASM_SI                __ASM_REG(si)
+#define _ASM_DI                __ASM_REG(di)
 
 /* Exception table entry */
 # define _ASM_EXTABLE(from,to) \
@@ -39,4 +44,4 @@
        _ASM_PTR #from "," #to "\n" \
        " .previous\n"
 
-#endif /* _ASM_X86_ASM_H */
+#endif /* ASM_X86__ASM_H */
index 21a4825148c09e34c70db728f68951ff32e631f8..14d3f0beb889917c3d6af356bdd84d114a7cae06 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ARCH_I386_ATOMIC__
-#define __ARCH_I386_ATOMIC__
+#ifndef ASM_X86__ATOMIC_32_H
+#define ASM_X86__ATOMIC_32_H
 
 #include <linux/compiler.h>
 #include <asm/processor.h>
@@ -256,4 +256,4 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u)
 #define smp_mb__after_atomic_inc()     barrier()
 
 #include <asm-generic/atomic.h>
-#endif
+#endif /* ASM_X86__ATOMIC_32_H */
index 91c7d03e65bcc077f4bbffe98cf662ee47bf33dc..2cb218c4a356ce332b2e887b88e8d146e602fe84 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ARCH_X86_64_ATOMIC__
-#define __ARCH_X86_64_ATOMIC__
+#ifndef ASM_X86__ATOMIC_64_H
+#define ASM_X86__ATOMIC_64_H
 
 #include <asm/alternative.h>
 #include <asm/cmpxchg.h>
@@ -470,4 +470,4 @@ static inline void atomic_or_long(unsigned long *v1, unsigned long v2)
 #define smp_mb__after_atomic_inc()     barrier()
 
 #include <asm-generic/atomic.h>
-#endif
+#endif /* ASM_X86__ATOMIC_64_H */
index 87f5e6d5a02075244fbd3ad2087ae9a8c9e4405a..12c7cac7420202c7a4a11997187b966bc4d392c4 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_AUXVEC_H
-#define _ASM_X86_AUXVEC_H
+#ifndef ASM_X86__AUXVEC_H
+#define ASM_X86__AUXVEC_H
 /*
  * Architecture-neutral AT_ values in 0-17, leave some room
  * for more of them, start the x86-specific ones at 32.
@@ -9,4 +9,4 @@
 #endif
 #define AT_SYSINFO_EHDR                33
 
-#endif
+#endif /* ASM_X86__AUXVEC_H */
index 0033e50c13b28cec6bfcd479ced48e01798e9e76..ec42ed8745913383cbb81be7c28556c4ddbacdd0 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _MACH_BIOS_EBDA_H
-#define _MACH_BIOS_EBDA_H
+#ifndef ASM_X86__BIOS_EBDA_H
+#define ASM_X86__BIOS_EBDA_H
 
 #include <asm/io.h>
 
@@ -16,4 +16,4 @@ static inline unsigned int get_bios_ebda(void)
 
 void reserve_ebda_region(void);
 
-#endif /* _MACH_BIOS_EBDA_H */
+#endif /* ASM_X86__BIOS_EBDA_H */
index cfb2b64f76e7d645a8418426f71239b80250c5bb..61989b93b4753db3f5758ba82308431379b1edda 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_BITOPS_H
-#define _ASM_X86_BITOPS_H
+#ifndef ASM_X86__BITOPS_H
+#define ASM_X86__BITOPS_H
 
 /*
  * Copyright 1992, Linus Torvalds.
@@ -458,4 +458,4 @@ static inline void set_bit_string(unsigned long *bitmap,
 #include <asm-generic/bitops/minix.h>
 
 #endif /* __KERNEL__ */
-#endif /* _ASM_X86_BITOPS_H */
+#endif /* ASM_X86__BITOPS_H */
index 2faed7ecb092a7893c89c573b7ac9870e060d8a7..825de5dc867cb97240a90ba3abc1c2933f3fee07 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_BOOT_H
-#define _ASM_BOOT_H
+#ifndef ASM_X86__BOOT_H
+#define ASM_X86__BOOT_H
 
 /* Don't touch these, unless you really know what you're doing. */
 #define DEF_INITSEG    0x9000
@@ -25,4 +25,4 @@
 #define BOOT_STACK_SIZE        0x1000
 #endif
 
-#endif /* _ASM_BOOT_H */
+#endif /* ASM_X86__BOOT_H */
index ae22bdf0ab14a74c4b9d01f91fb07230047e1cee..ccf027e2d97da02eabaab3d54eea8bd4fe727d87 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_BOOTPARAM_H
-#define _ASM_BOOTPARAM_H
+#ifndef ASM_X86__BOOTPARAM_H
+#define ASM_X86__BOOTPARAM_H
 
 #include <linux/types.h>
 #include <linux/screen_info.h>
@@ -108,4 +108,4 @@ struct boot_params {
        __u8  _pad9[276];                               /* 0xeec */
 } __attribute__((packed));
 
-#endif /* _ASM_BOOTPARAM_H */
+#endif /* ASM_X86__BOOTPARAM_H */
index b69aa64b82a4af9e60573253abdb5a9c07ebc8e8..91ad43a54c47c6f9b9cb28bfc3cb7003a7b666a1 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_BUG_H
-#define _ASM_X86_BUG_H
+#ifndef ASM_X86__BUG_H
+#define ASM_X86__BUG_H
 
 #ifdef CONFIG_BUG
 #define HAVE_ARCH_BUG
@@ -36,4 +36,4 @@ do {                                                          \
 #endif /* !CONFIG_BUG */
 
 #include <asm-generic/bug.h>
-#endif
+#endif /* ASM_X86__BUG_H */
index 021cbdd5f258a7739c2433d62f00a37a51070a4b..4761c461d23a62a4ba44e015c106bd5d5bdbd02c 100644 (file)
@@ -1,7 +1,7 @@
-#ifndef _ASM_X86_BUGS_H
-#define _ASM_X86_BUGS_H
+#ifndef ASM_X86__BUGS_H
+#define ASM_X86__BUGS_H
 
 extern void check_bugs(void);
 int ppro_with_ram_bug(void);
 
-#endif /* _ASM_X86_BUGS_H */
+#endif /* ASM_X86__BUGS_H */
index e02ae2d89acf13936aad26502e485aa6ddae0b65..722f27d68105f8e454ccaf01d1b7de4baa8dd0ce 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_BYTEORDER_H
-#define _ASM_X86_BYTEORDER_H
+#ifndef ASM_X86__BYTEORDER_H
+#define ASM_X86__BYTEORDER_H
 
 #include <asm/types.h>
 #include <linux/compiler.h>
@@ -78,4 +78,4 @@ static inline __attribute_const__ __u32 ___arch__swab32(__u32 x)
 
 #include <linux/byteorder/little_endian.h>
 
-#endif /* _ASM_X86_BYTEORDER_H */
+#endif /* ASM_X86__BYTEORDER_H */
index 1e0bac86f38f8ee4f950380e4e1845a49fec6b30..ea3f1cc06a974e8d3255bb07e74777f390976afa 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ARCH_X86_CACHE_H
-#define _ARCH_X86_CACHE_H
+#ifndef ASM_X86__CACHE_H
+#define ASM_X86__CACHE_H
 
 /* L1 cache line size */
 #define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT)
@@ -17,4 +17,4 @@
 #endif
 #endif
 
-#endif
+#endif /* ASM_X86__CACHE_H */
index f4c0ab50d2c2bc4d8e5d5beea1c84c26409225d7..59859cb28a36ce486478f147f79c7bdfa26ae5f7 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_CACHEFLUSH_H
-#define _ASM_X86_CACHEFLUSH_H
+#ifndef ASM_X86__CACHEFLUSH_H
+#define ASM_X86__CACHEFLUSH_H
 
 /* Keep includes the same across arches.  */
 #include <linux/mm.h>
@@ -112,4 +112,4 @@ static inline int rodata_test(void)
 }
 #endif
 
-#endif
+#endif /* ASM_X86__CACHEFLUSH_H */
index 67f60406e2d8136ac50b3b25afefef629508ec0d..933fd272f82663c6ed0c2224df4e668a0870681c 100644 (file)
@@ -21,8 +21,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
-#ifndef _ASM_X86_64_CALGARY_H
-#define _ASM_X86_64_CALGARY_H
+#ifndef ASM_X86__CALGARY_H
+#define ASM_X86__CALGARY_H
 
 #include <linux/spinlock.h>
 #include <linux/device.h>
@@ -69,4 +69,4 @@ static inline int calgary_iommu_init(void) { return 1; }
 static inline void detect_calgary(void) { return; }
 #endif
 
-#endif /* _ASM_X86_64_CALGARY_H */
+#endif /* ASM_X86__CALGARY_H */
index 52bbb0d8c4c15ce08c2d155fc23f031b98384547..d041e8cda227a6b191f70052599b00383af83ea7 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _I386_CHECKSUM_H
-#define _I386_CHECKSUM_H
+#ifndef ASM_X86__CHECKSUM_32_H
+#define ASM_X86__CHECKSUM_32_H
 
 #include <linux/in6.h>
 
@@ -186,4 +186,4 @@ static inline __wsum csum_and_copy_to_user(const void *src,
        return (__force __wsum)-1; /* invalid checksum */
 }
 
-#endif
+#endif /* ASM_X86__CHECKSUM_32_H */
index 8bd861cc5267094b38fb43f2452b4578d87fb405..110f403beb8953d60218bc5b8c940b9f92dc80bd 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _X86_64_CHECKSUM_H
-#define _X86_64_CHECKSUM_H
+#ifndef ASM_X86__CHECKSUM_64_H
+#define ASM_X86__CHECKSUM_64_H
 
 /*
  * Checksums for x86-64
@@ -188,4 +188,4 @@ static inline unsigned add32_with_carry(unsigned a, unsigned b)
        return a;
 }
 
-#endif
+#endif /* ASM_X86__CHECKSUM_64_H */
index bf5a69d1329ef827a636778829a42bae261910aa..0622e45cdf7cf2b26413e506ef98a0352d6fb400 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_CMPXCHG_H
-#define __ASM_CMPXCHG_H
+#ifndef ASM_X86__CMPXCHG_32_H
+#define ASM_X86__CMPXCHG_32_H
 
 #include <linux/bitops.h> /* for LOCK_PREFIX */
 
@@ -341,4 +341,4 @@ extern unsigned long long cmpxchg_486_u64(volatile void *, u64, u64);
 
 #endif
 
-#endif
+#endif /* ASM_X86__CMPXCHG_32_H */
index 17463ccf816618b59a144ec76f57e51589e8866c..63c1a5e61b994a781ef3ff8e9c1f858e9afac264 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_CMPXCHG_H
-#define __ASM_CMPXCHG_H
+#ifndef ASM_X86__CMPXCHG_64_H
+#define ASM_X86__CMPXCHG_64_H
 
 #include <asm/alternative.h> /* Provides LOCK_PREFIX */
 
@@ -182,4 +182,4 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr,
        cmpxchg_local((ptr), (o), (n));                                 \
 })
 
-#endif
+#endif /* ASM_X86__CMPXCHG_64_H */
index 1793ac317a30417523cc84fb5d4b2f583b1b4a01..6732b150949e8c8ef0b333673c5b92438c3a9a9e 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_64_COMPAT_H
-#define _ASM_X86_64_COMPAT_H
+#ifndef ASM_X86__COMPAT_H
+#define ASM_X86__COMPAT_H
 
 /*
  * Architecture specific compatibility types
@@ -215,4 +215,4 @@ static inline int is_compat_task(void)
        return current_thread_info()->status & TS_COMPAT;
 }
 
-#endif /* _ASM_X86_64_COMPAT_H */
+#endif /* ASM_X86__COMPAT_H */
index 73f2ea84fd74b024fa4ebc8e91cabcdab4340108..83a115083f0d74ad3eb0f82eae64e19aea5a7cc1 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_I386_CPU_H_
-#define _ASM_I386_CPU_H_
+#ifndef ASM_X86__CPU_H
+#define ASM_X86__CPU_H
 
 #include <linux/device.h>
 #include <linux/cpu.h>
@@ -17,4 +17,4 @@ extern void arch_unregister_cpu(int);
 #endif
 
 DECLARE_PER_CPU(int, cpu_state);
-#endif /* _ASM_I386_CPU_H_ */
+#endif /* ASM_X86__CPU_H */
index cfcfb0a806bac0d6f591c272c3ad3f65c384d0fe..250fa0cb144b9f3c4f34254f599c43a5e75acd9f 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Defines x86 CPU feature bits
  */
-#ifndef _ASM_X86_CPUFEATURE_H
-#define _ASM_X86_CPUFEATURE_H
+#ifndef ASM_X86__CPUFEATURE_H
+#define ASM_X86__CPUFEATURE_H
 
 #include <asm/required-features.h>
 
@@ -224,4 +224,4 @@ extern const char * const x86_power_flags[32];
 
 #endif /* defined(__KERNEL__) && !defined(__ASSEMBLY__) */
 
-#endif /* _ASM_X86_CPUFEATURE_H */
+#endif /* ASM_X86__CPUFEATURE_H */
index 7515c19d498884d770e901740eb506d5f96c4807..a863ead856f3d37de49d023a156f98b1d4f540c5 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _X86_CURRENT_H
-#define _X86_CURRENT_H
+#ifndef ASM_X86__CURRENT_H
+#define ASM_X86__CURRENT_H
 
 #ifdef CONFIG_X86_32
 #include <linux/compiler.h>
@@ -36,4 +36,4 @@ static __always_inline struct task_struct *get_current(void)
 
 #define current get_current()
 
-#endif /* X86_CURRENT_H */
+#endif /* ASM_X86__CURRENT_H */
index c6344d572b033a78d04d1219f9772f6fab8b7f06..ecb6907c3ea4ff97ef7aacb4b9c47809ef2701c4 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_DEBUGREG_H
-#define _ASM_X86_DEBUGREG_H
+#ifndef ASM_X86__DEBUGREG_H
+#define ASM_X86__DEBUGREG_H
 
 
 /* Indicate the register numbers for a number of the specific
@@ -67,4 +67,4 @@
 #define DR_LOCAL_SLOWDOWN (0x100)   /* Local slow the pipeline */
 #define DR_GLOBAL_SLOWDOWN (0x200)  /* Global slow the pipeline */
 
-#endif
+#endif /* ASM_X86__DEBUGREG_H */
index 409a649204aa7308c8936d6cc08d4479222d6885..8a0da95b4fc50e290187fd3bf3eb05b161fdf955 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_DELAY_H
-#define _ASM_X86_DELAY_H
+#ifndef ASM_X86__DELAY_H
+#define ASM_X86__DELAY_H
 
 /*
  * Copyright (C) 1993 Linus Torvalds
@@ -28,4 +28,4 @@ extern void __delay(unsigned long loops);
 
 void use_tsc_delay(void);
 
-#endif /* _ASM_X86_DELAY_H */
+#endif /* ASM_X86__DELAY_H */
index a44c4dc705902c6b1e76c92d71f1c68f759a0df4..b73fea54def29e1dfd0d2e95ec65f08c64b5cb49 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_DESC_H_
-#define _ASM_DESC_H_
+#ifndef ASM_X86__DESC_H
+#define ASM_X86__DESC_H
 
 #ifndef __ASSEMBLY__
 #include <asm/desc_defs.h>
@@ -397,4 +397,4 @@ static inline void set_system_gate_ist(int n, void *addr, unsigned ist)
 
 #endif /* __ASSEMBLY__ */
 
-#endif
+#endif /* ASM_X86__DESC_H */
index f7bacf357daca2be4fb7345d75deb69c6c6c0ee3..b881db664b46a27927d9febc4f16e39e24227d49 100644 (file)
@@ -1,6 +1,6 @@
 /* Written 2000 by Andi Kleen */
-#ifndef __ARCH_DESC_DEFS_H
-#define __ARCH_DESC_DEFS_H
+#ifndef ASM_X86__DESC_DEFS_H
+#define ASM_X86__DESC_DEFS_H
 
 /*
  * Segment descriptor structure definitions, usable from both x86_64 and i386
@@ -92,4 +92,4 @@ struct desc_ptr {
 
 #endif /* !__ASSEMBLY__ */
 
-#endif
+#endif /* ASM_X86__DESC_DEFS_H */
index 3c034f48fdb0a12f5a3fefe1499d014b68e6f4a2..1bece04c7d9d9b829d6d51abe191ce1b8abf0da9 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_DEVICE_H
-#define _ASM_X86_DEVICE_H
+#ifndef ASM_X86__DEVICE_H
+#define ASM_X86__DEVICE_H
 
 struct dev_archdata {
 #ifdef CONFIG_ACPI
@@ -13,4 +13,4 @@ struct dma_mapping_ops *dma_ops;
 #endif
 };
 
-#endif /* _ASM_X86_DEVICE_H */
+#endif /* ASM_X86__DEVICE_H */
index 9a2d644c08efc0981dbc13b1700e81917fef7c63..f9530f23f1d6ac2e4577ec036748cbbbc4752a93 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_DIV64_H
-#define _ASM_X86_DIV64_H
+#ifndef ASM_X86__DIV64_H
+#define ASM_X86__DIV64_H
 
 #ifdef CONFIG_X86_32
 
@@ -57,4 +57,4 @@ static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
 # include <asm-generic/div64.h>
 #endif /* CONFIG_X86_32 */
 
-#endif /* _ASM_X86_DIV64_H */
+#endif /* ASM_X86__DIV64_H */
index ad9cd6d49bfc9bc624747709da188301b35f5b55..5d200e78bd81e18b7e315f8f2d9660cd13c23a1d 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_DMA_MAPPING_H_
-#define _ASM_DMA_MAPPING_H_
+#ifndef ASM_X86__DMA_MAPPING_H
+#define ASM_X86__DMA_MAPPING_H
 
 /*
  * IOMMU interface. See Documentation/DMA-mapping.txt and DMA-API.txt for
@@ -250,4 +250,4 @@ static inline int dma_get_cache_alignment(void)
 #define dma_is_consistent(d, h)        (1)
 
 #include <asm-generic/dma-coherent.h>
-#endif
+#endif /* ASM_X86__DMA_MAPPING_H */
index ca1098a7e58057eebe268c059a682990c6ebb7e6..c9f7a4eec5557c7ce8ee02b67af6daa6dd234062 100644 (file)
@@ -5,8 +5,8 @@
  * and John Boyd, Nov. 1992.
  */
 
-#ifndef _ASM_X86_DMA_H
-#define _ASM_X86_DMA_H
+#ifndef ASM_X86__DMA_H
+#define ASM_X86__DMA_H
 
 #include <linux/spinlock.h>    /* And spinlocks */
 #include <asm/io.h>            /* need byte IO */
@@ -315,4 +315,4 @@ extern int isa_dma_bridge_buggy;
 #define isa_dma_bridge_buggy   (0)
 #endif
 
-#endif /* _ASM_X86_DMA_H */
+#endif /* ASM_X86__DMA_H */
index 58a86571fe0f8451df8800bd87b218e2be028886..1cff6fe81fa5cb9d4f20954fca9e192cd99419a9 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_DMI_H
-#define _ASM_X86_DMI_H
+#ifndef ASM_X86__DMI_H
+#define ASM_X86__DMI_H
 
 #include <asm/io.h>
 
@@ -23,4 +23,4 @@ static inline void *dmi_alloc(unsigned len)
 #define dmi_ioremap early_ioremap
 #define dmi_iounmap early_iounmap
 
-#endif
+#endif /* ASM_X86__DMI_H */
index 7881368142faaad53fe374c60aff964a69549770..c3c953a45b215ba24b3c4216f4ee9def2e1f7c08 100644 (file)
  * Debug Store (DS) support
  *
  * This provides a low-level interface to the hardware's Debug Store
- * feature that is used for last branch recording (LBR) and
+ * feature that is used for branch trace store (BTS) and
  * precise-event based sampling (PEBS).
  *
- * Different architectures use a different DS layout/pointer size.
- * The below functions therefore work on a void*.
+ * It manages:
+ * - per-thread and per-cpu allocation of BTS and PEBS
+ * - buffer memory allocation (optional)
+ * - buffer overflow handling
+ * - buffer access
  *
+ * It assumes:
+ * - get_task_struct on all parameter tasks
+ * - current is allowed to trace parameter tasks
  *
- * Since there is no user for PEBS, yet, only LBR (or branch
- * trace store, BTS) is supported.
  *
- *
- * Copyright (C) 2007 Intel Corporation.
- * Markus Metzger <markus.t.metzger@intel.com>, Dec 2007
+ * Copyright (C) 2007-2008 Intel Corporation.
+ * Markus Metzger <markus.t.metzger@intel.com>, 2007-2008
  */
 
-#ifndef _ASM_X86_DS_H
-#define _ASM_X86_DS_H
+#ifndef ASM_X86__DS_H
+#define ASM_X86__DS_H
+
+#ifdef CONFIG_X86_DS
 
 #include <linux/types.h>
 #include <linux/init.h>
 
-struct cpuinfo_x86;
 
+struct task_struct;
 
-/* a branch trace record entry
+/*
+ * Request BTS or PEBS
+ *
+ * Due to alignement constraints, the actual buffer may be slightly
+ * smaller than the requested or provided buffer.
  *
- * In order to unify the interface between various processor versions,
- * we use the below data structure for all processors.
+ * Returns 0 on success; -Eerrno otherwise
+ *
+ * task: the task to request recording for;
+ *       NULL for per-cpu recording on the current cpu
+ * base: the base pointer for the (non-pageable) buffer;
+ *       NULL if buffer allocation requested
+ * size: the size of the requested or provided buffer
+ * ovfl: pointer to a function to be called on buffer overflow;
+ *       NULL if cyclic buffer requested
  */
-enum bts_qualifier {
-       BTS_INVALID = 0,
-       BTS_BRANCH,
-       BTS_TASK_ARRIVES,
-       BTS_TASK_DEPARTS
-};
+typedef void (*ds_ovfl_callback_t)(struct task_struct *);
+extern int ds_request_bts(struct task_struct *task, void *base, size_t size,
+                         ds_ovfl_callback_t ovfl);
+extern int ds_request_pebs(struct task_struct *task, void *base, size_t size,
+                          ds_ovfl_callback_t ovfl);
 
-struct bts_struct {
-       u64 qualifier;
-       union {
-               /* BTS_BRANCH */
-               struct {
-                       u64 from_ip;
-                       u64 to_ip;
-               } lbr;
-               /* BTS_TASK_ARRIVES or
-                  BTS_TASK_DEPARTS */
-               u64 jiffies;
-       } variant;
+/*
+ * Release BTS or PEBS resources
+ *
+ * Frees buffers allocated on ds_request.
+ *
+ * Returns 0 on success; -Eerrno otherwise
+ *
+ * task: the task to release resources for;
+ *       NULL to release resources for the current cpu
+ */
+extern int ds_release_bts(struct task_struct *task);
+extern int ds_release_pebs(struct task_struct *task);
+
+/*
+ * Return the (array) index of the write pointer.
+ * (assuming an array of BTS/PEBS records)
+ *
+ * Returns -Eerrno on error
+ *
+ * task: the task to access;
+ *       NULL to access the current cpu
+ * pos (out): if not NULL, will hold the result
+ */
+extern int ds_get_bts_index(struct task_struct *task, size_t *pos);
+extern int ds_get_pebs_index(struct task_struct *task, size_t *pos);
+
+/*
+ * Return the (array) index one record beyond the end of the array.
+ * (assuming an array of BTS/PEBS records)
+ *
+ * Returns -Eerrno on error
+ *
+ * task: the task to access;
+ *       NULL to access the current cpu
+ * pos (out): if not NULL, will hold the result
+ */
+extern int ds_get_bts_end(struct task_struct *task, size_t *pos);
+extern int ds_get_pebs_end(struct task_struct *task, size_t *pos);
+
+/*
+ * Provide a pointer to the BTS/PEBS record at parameter index.
+ * (assuming an array of BTS/PEBS records)
+ *
+ * The pointer points directly into the buffer. The user is
+ * responsible for copying the record.
+ *
+ * Returns the size of a single record on success; -Eerrno on error
+ *
+ * task: the task to access;
+ *       NULL to access the current cpu
+ * index: the index of the requested record
+ * record (out): pointer to the requested record
+ */
+extern int ds_access_bts(struct task_struct *task,
+                        size_t index, const void **record);
+extern int ds_access_pebs(struct task_struct *task,
+                         size_t index, const void **record);
+
+/*
+ * Write one or more BTS/PEBS records at the write pointer index and
+ * advance the write pointer.
+ *
+ * If size is not a multiple of the record size, trailing bytes are
+ * zeroed out.
+ *
+ * May result in one or more overflow notifications.
+ *
+ * If called during overflow handling, that is, with index >=
+ * interrupt threshold, the write will wrap around.
+ *
+ * An overflow notification is given if and when the interrupt
+ * threshold is reached during or after the write.
+ *
+ * Returns the number of bytes written or -Eerrno.
+ *
+ * task: the task to access;
+ *       NULL to access the current cpu
+ * buffer: the buffer to write
+ * size: the size of the buffer
+ */
+extern int ds_write_bts(struct task_struct *task,
+                       const void *buffer, size_t size);
+extern int ds_write_pebs(struct task_struct *task,
+                        const void *buffer, size_t size);
+
+/*
+ * Same as ds_write_bts/pebs, but omit ownership checks.
+ *
+ * This is needed to have some other task than the owner of the
+ * BTS/PEBS buffer or the parameter task itself write into the
+ * respective buffer.
+ */
+extern int ds_unchecked_write_bts(struct task_struct *task,
+                                 const void *buffer, size_t size);
+extern int ds_unchecked_write_pebs(struct task_struct *task,
+                                  const void *buffer, size_t size);
+
+/*
+ * Reset the write pointer of the BTS/PEBS buffer.
+ *
+ * Returns 0 on success; -Eerrno on error
+ *
+ * task: the task to access;
+ *       NULL to access the current cpu
+ */
+extern int ds_reset_bts(struct task_struct *task);
+extern int ds_reset_pebs(struct task_struct *task);
+
+/*
+ * Clear the BTS/PEBS buffer and reset the write pointer.
+ * The entire buffer will be zeroed out.
+ *
+ * Returns 0 on success; -Eerrno on error
+ *
+ * task: the task to access;
+ *       NULL to access the current cpu
+ */
+extern int ds_clear_bts(struct task_struct *task);
+extern int ds_clear_pebs(struct task_struct *task);
+
+/*
+ * Provide the PEBS counter reset value.
+ *
+ * Returns 0 on success; -Eerrno on error
+ *
+ * task: the task to access;
+ *       NULL to access the current cpu
+ * value (out): the counter reset value
+ */
+extern int ds_get_pebs_reset(struct task_struct *task, u64 *value);
+
+/*
+ * Set the PEBS counter reset value.
+ *
+ * Returns 0 on success; -Eerrno on error
+ *
+ * task: the task to access;
+ *       NULL to access the current cpu
+ * value: the new counter reset value
+ */
+extern int ds_set_pebs_reset(struct task_struct *task, u64 value);
+
+/*
+ * Initialization
+ */
+struct cpuinfo_x86;
+extern void __cpuinit ds_init_intel(struct cpuinfo_x86 *);
+
+
+
+/*
+ * The DS context - part of struct thread_struct.
+ */
+struct ds_context {
+       /* pointer to the DS configuration; goes into MSR_IA32_DS_AREA */
+       unsigned char *ds;
+       /* the owner of the BTS and PEBS configuration, respectively */
+       struct task_struct *owner[2];
+       /* buffer overflow notification function for BTS and PEBS */
+       ds_ovfl_callback_t callback[2];
+       /* the original buffer address */
+       void *buffer[2];
+       /* the number of allocated pages for on-request allocated buffers */
+       unsigned int pages[2];
+       /* use count */
+       unsigned long count;
+       /* a pointer to the context location inside the thread_struct
+        * or the per_cpu context array */
+       struct ds_context **this;
+       /* a pointer to the task owning this context, or NULL, if the
+        * context is owned by a cpu */
+       struct task_struct *task;
 };
 
-/* Overflow handling mechanisms */
-#define DS_O_SIGNAL    1 /* send overflow signal */
-#define DS_O_WRAP      2 /* wrap around */
-
-extern int ds_allocate(void **, size_t);
-extern int ds_free(void **);
-extern int ds_get_bts_size(void *);
-extern int ds_get_bts_end(void *);
-extern int ds_get_bts_index(void *);
-extern int ds_set_overflow(void *, int);
-extern int ds_get_overflow(void *);
-extern int ds_clear(void *);
-extern int ds_read_bts(void *, int, struct bts_struct *);
-extern int ds_write_bts(void *, const struct bts_struct *);
-extern unsigned long ds_debugctl_mask(void);
-extern void __cpuinit ds_init_intel(struct cpuinfo_x86 *c);
-
-#endif /* _ASM_X86_DS_H */
+/* called by exit_thread() to free leftover contexts */
+extern void ds_free(struct ds_context *context);
+
+#else /* CONFIG_X86_DS */
+
+#define ds_init_intel(config) do {} while (0)
+
+#endif /* CONFIG_X86_DS */
+#endif /* ASM_X86__DS_H */
index 738bb9fb3e53c86ddb40119158b1b88307a5ab35..21d1bc32ad7c37ee7fa0213b2af692d73be0157a 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _DWARF2_H
-#define _DWARF2_H
+#ifndef ASM_X86__DWARF2_H
+#define ASM_X86__DWARF2_H
 
 #ifndef __ASSEMBLY__
 #warning "asm/dwarf2.h should be only included in pure assembly files"
@@ -58,4 +58,4 @@
 
 #endif
 
-#endif
+#endif /* ASM_X86__DWARF2_H */
index 16a31e2c7c5747888b0c75178bb0683859dbbac1..f52daf176bcbba7c25a04677153bd0429a402050 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_E820_H
-#define __ASM_E820_H
+#ifndef ASM_X86__E820_H
+#define ASM_X86__E820_H
 #define E820MAP        0x2d0           /* our map */
 #define E820MAX        128             /* number of entries in E820MAP */
 
@@ -64,6 +64,7 @@ struct e820map {
 extern struct e820map e820;
 extern struct e820map e820_saved;
 
+extern unsigned long pci_mem_start;
 extern int e820_any_mapped(u64 start, u64 end, unsigned type);
 extern int e820_all_mapped(u64 start, u64 end, unsigned type);
 extern void e820_add_region(u64 start, u64 size, int type);
@@ -140,4 +141,4 @@ extern char *memory_setup(void);
 #define HIGH_MEMORY    (1024*1024)
 #endif /* __KERNEL__ */
 
-#endif  /* __ASM_E820_H */
+#endif /* ASM_X86__E820_H */
index a8088f63a30e4a58cfd50dde612e7da94843b3d0..9493c5b27bbdb4584bc60ff98b4fae0fd2dfc54f 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_EDAC_H
-#define _ASM_X86_EDAC_H
+#ifndef ASM_X86__EDAC_H
+#define ASM_X86__EDAC_H
 
 /* ECC atomic, DMA, SMP and interrupt safe scrub function */
 
@@ -15,4 +15,4 @@ static inline void atomic_scrub(void *va, u32 size)
                asm volatile("lock; addl $0, %0"::"m" (*virt_addr));
 }
 
-#endif
+#endif /* ASM_X86__EDAC_H */
index d4f2b0abe9294eefce100885a7c342bea885d0c5..ed2de22e87050089bb8a8c02fb85bc0a204d2141 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_EFI_H
-#define _ASM_X86_EFI_H
+#ifndef ASM_X86__EFI_H
+#define ASM_X86__EFI_H
 
 #ifdef CONFIG_X86_32
 
@@ -94,4 +94,4 @@ extern void efi_reserve_early(void);
 extern void efi_call_phys_prelog(void);
 extern void efi_call_phys_epilog(void);
 
-#endif
+#endif /* ASM_X86__EFI_H */
index 7be4733c793e58c404fbab54d3c34e2e05ff8aa0..5c4745bec9061c0febdfb21ab4534c89c8f354f9 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_ELF_H
-#define _ASM_X86_ELF_H
+#ifndef ASM_X86__ELF_H
+#define ASM_X86__ELF_H
 
 /*
  * ELF register definitions..
@@ -148,8 +148,9 @@ do {                                                \
 
 static inline void start_ia32_thread(struct pt_regs *regs, u32 ip, u32 sp)
 {
-       asm volatile("movl %0,%%fs" :: "r" (0));
-       asm volatile("movl %0,%%es; movl %0,%%ds" : : "r" (__USER32_DS));
+       loadsegment(fs, 0);
+       loadsegment(ds, __USER32_DS);
+       loadsegment(es, __USER32_DS);
        load_gs_index(0);
        regs->ip = ip;
        regs->sp = sp;
@@ -332,4 +333,4 @@ extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
 extern unsigned long arch_randomize_brk(struct mm_struct *mm);
 #define arch_randomize_brk arch_randomize_brk
 
-#endif
+#endif /* ASM_X86__ELF_H */
index 8e6aef19f8f02ce8be4edf1cf346ac9b257aaa77..190d0d8b71e330e35d1b0da257ab38132f218db3 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_EMERGENCY_RESTART_H
-#define _ASM_EMERGENCY_RESTART_H
+#ifndef ASM_X86__EMERGENCY_RESTART_H
+#define ASM_X86__EMERGENCY_RESTART_H
 
 enum reboot_type {
        BOOT_TRIPLE = 't',
@@ -15,4 +15,4 @@ extern enum reboot_type reboot_type;
 
 extern void machine_emergency_restart(void);
 
-#endif /* _ASM_EMERGENCY_RESTART_H */
+#endif /* ASM_X86__EMERGENCY_RESTART_H */
index 53018464aea653a407dc32e6be3d95ac14230306..aca38dbd9a644981541ef3cedeaea57d373d8d2c 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_FB_H
-#define _ASM_X86_FB_H
+#ifndef ASM_X86__FB_H
+#define ASM_X86__FB_H
 
 #include <linux/fb.h>
 #include <linux/fs.h>
@@ -18,4 +18,4 @@ extern int fb_is_primary_device(struct fb_info *info);
 static inline int fb_is_primary_device(struct fb_info *info) { return 0; }
 #endif
 
-#endif /* _ASM_X86_FB_H */
+#endif /* ASM_X86__FB_H */
index 44d4f82173496d2984b9c6612c4d4fe48341a146..78e33a1bc591ea67357cc8bee1efdeb4d75463e6 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_FIXMAP_H
-#define _ASM_FIXMAP_H
+#ifndef ASM_X86__FIXMAP_H
+#define ASM_X86__FIXMAP_H
 
 #ifdef CONFIG_X86_32
 # include "fixmap_32.h"
@@ -65,4 +65,4 @@ static inline unsigned long virt_to_fix(const unsigned long vaddr)
        BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
        return __virt_to_fix(vaddr);
 }
-#endif
+#endif /* ASM_X86__FIXMAP_H */
index f1ac2b2167d7fdf0ba27c450d2c688f05c3b9e02..784e3e759866cc0025b4dd4e9af77aeedddcdd1d 100644 (file)
@@ -10,8 +10,8 @@
  * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
  */
 
-#ifndef _ASM_FIXMAP_32_H
-#define _ASM_FIXMAP_32_H
+#ifndef ASM_X86__FIXMAP_32_H
+#define ASM_X86__FIXMAP_32_H
 
 
 /* used by vmalloc.c, vsyscall.lds.S.
@@ -120,4 +120,4 @@ extern void reserve_top_address(unsigned long reserve);
 #define FIXADDR_BOOT_START     (FIXADDR_TOP - __FIXADDR_BOOT_SIZE)
 
 #endif /* !__ASSEMBLY__ */
-#endif
+#endif /* ASM_X86__FIXMAP_32_H */
index 00f3d74a0524d71e77bfb4730a8b6c13f38b052f..dafb24bc0424efd4b94ed18ae2ce5e1dcf4d0260 100644 (file)
@@ -8,8 +8,8 @@
  * Copyright (C) 1998 Ingo Molnar
  */
 
-#ifndef _ASM_FIXMAP_64_H
-#define _ASM_FIXMAP_64_H
+#ifndef ASM_X86__FIXMAP_64_H
+#define ASM_X86__FIXMAP_64_H
 
 #include <linux/kernel.h>
 #include <asm/acpi.h>
@@ -80,4 +80,4 @@ enum fixed_addresses {
 #define FIXADDR_USER_START     ((unsigned long)VSYSCALL32_VSYSCALL)
 #define FIXADDR_USER_END       (FIXADDR_USER_START + PAGE_SIZE)
 
-#endif
+#endif /* ASM_X86__FIXMAP_64_H */
index dbe82a5c5eacde33f9cdf3791dfe159228f151b6..7d83a3a83e3772ed54b5e0464c94aa8506421038 100644 (file)
@@ -7,8 +7,8 @@
  *
  * Copyright (C) 1995
  */
-#ifndef _ASM_X86_FLOPPY_H
-#define _ASM_X86_FLOPPY_H
+#ifndef ASM_X86__FLOPPY_H
+#define ASM_X86__FLOPPY_H
 
 #include <linux/vmalloc.h>
 
@@ -278,4 +278,4 @@ static int FDC2 = -1;
 
 #define EXTRA_FLOPPY_PARAMS
 
-#endif /* _ASM_X86_FLOPPY_H */
+#endif /* ASM_X86__FLOPPY_H */
index 5c68b32ee1c81c28a51392303f767f05cf9ae5f3..be0e004ad148123fc5f4b85e2c5a6c2ce8569aea 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_FTRACE
-#define _ASM_X86_FTRACE
+#ifndef ASM_X86__FTRACE_H
+#define ASM_X86__FTRACE_H
 
 #ifdef CONFIG_FTRACE
 #define MCOUNT_ADDR            ((long)(mcount))
@@ -11,4 +11,4 @@ extern void mcount(void);
 
 #endif /* CONFIG_FTRACE */
 
-#endif /* _ASM_X86_FTRACE */
+#endif /* ASM_X86__FTRACE_H */
index e7a76b37b333cc8b40295d7379f8cbb46b241a29..06b924ef6fa5b928dc6a6d83889ee6ce98cc157c 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_FUTEX_H
-#define _ASM_X86_FUTEX_H
+#ifndef ASM_X86__FUTEX_H
+#define ASM_X86__FUTEX_H
 
 #ifdef __KERNEL__
 
@@ -25,7 +25,7 @@
        asm volatile("1:\tmovl  %2, %0\n"                       \
                     "\tmovl\t%0, %3\n"                         \
                     "\t" insn "\n"                             \
-                    "2:\tlock; cmpxchgl %3, %2\n"              \
+                    "2:\t" LOCK_PREFIX "cmpxchgl %3, %2\n"     \
                     "\tjnz\t1b\n"                              \
                     "3:\t.section .fixup,\"ax\"\n"             \
                     "4:\tmov\t%5, %1\n"                        \
@@ -64,7 +64,7 @@ static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
                __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
                break;
        case FUTEX_OP_ADD:
-               __futex_atomic_op1("lock; xaddl %0, %2", ret, oldval,
+               __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret, oldval,
                                   uaddr, oparg);
                break;
        case FUTEX_OP_OR:
@@ -122,7 +122,7 @@ static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval,
        if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
                return -EFAULT;
 
-       asm volatile("1:\tlock; cmpxchgl %3, %1\n"
+       asm volatile("1:\t" LOCK_PREFIX "cmpxchgl %3, %1\n"
                     "2:\t.section .fixup, \"ax\"\n"
                     "3:\tmov     %2, %0\n"
                     "\tjmp     2b\n"
@@ -137,4 +137,4 @@ static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval,
 }
 
 #endif
-#endif
+#endif /* ASM_X86__FUTEX_H */
index 3f62a83887f32c21c0919dd5c255847a8e6c2740..baa54faba89204b3e62fd263420fc93e4888af9e 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X8664_GART_H
-#define _ASM_X8664_GART_H 1
+#ifndef ASM_X86__GART_H
+#define ASM_X86__GART_H
 
 #include <asm/e820.h>
 
@@ -52,15 +52,15 @@ static inline int aperture_valid(u64 aper_base, u32 aper_size, u32 min_size)
                return 0;
 
        if (aper_base + aper_size > 0x100000000ULL) {
-               printk(KERN_ERR "Aperture beyond 4GB. Ignoring.\n");
+               printk(KERN_INFO "Aperture beyond 4GB. Ignoring.\n");
                return 0;
        }
        if (e820_any_mapped(aper_base, aper_base + aper_size, E820_RAM)) {
-               printk(KERN_ERR "Aperture pointing to e820 RAM. Ignoring.\n");
+               printk(KERN_INFO "Aperture pointing to e820 RAM. Ignoring.\n");
                return 0;
        }
        if (aper_size < min_size) {
-               printk(KERN_ERR "Aperture too small (%d MB) than (%d MB)\n",
+               printk(KERN_INFO "Aperture too small (%d MB) than (%d MB)\n",
                                 aper_size>>20, min_size>>20);
                return 0;
        }
@@ -68,4 +68,4 @@ static inline int aperture_valid(u64 aper_base, u32 aper_size, u32 min_size)
        return 1;
 }
 
-#endif
+#endif /* ASM_X86__GART_H */
index 754d635f90ffc9514a1daae0ed560eed9d629cd9..34280f027664a57267d915bda709183b745ea9a5 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_GENAPIC_H
-#define _ASM_GENAPIC_H 1
+#ifndef ASM_X86__GENAPIC_32_H
+#define ASM_X86__GENAPIC_32_H
 
 #include <asm/mpspec.h>
 
@@ -121,4 +121,4 @@ enum uv_system_type {UV_NONE, UV_LEGACY_APIC, UV_X2APIC, UV_NON_UNIQUE_APIC};
 #define uv_system_init()               do {} while (0)
 
 
-#endif
+#endif /* ASM_X86__GENAPIC_32_H */
index a47d6312913596fbd0a8a77c54ed8b45937a5a90..25097a8cc5efd8cb3f59f5ad980c9de41955f567 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_GENAPIC_H
-#define _ASM_GENAPIC_H 1
+#ifndef ASM_X86__GENAPIC_64_H
+#define ASM_X86__GENAPIC_64_H
 
 /*
  * Copyright 2004 James Cleverdon, IBM.
@@ -47,4 +47,4 @@ extern int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip);
 
 extern void setup_apic_routing(void);
 
-#endif
+#endif /* ASM_X86__GENAPIC_64_H */
index 2c1cda0b8a860502aac60502b59fd4f9c9a9a895..3f3444be2638f7205d17dc432d723e5b58fcb3f1 100644 (file)
@@ -7,8 +7,8 @@
  * as published by the Free Software Foundation.
  */
 
-#ifndef _ASM_GEODE_H_
-#define _ASM_GEODE_H_
+#ifndef ASM_X86__GEODE_H
+#define ASM_X86__GEODE_H
 
 #include <asm/processor.h>
 #include <linux/io.h>
@@ -250,4 +250,4 @@ extern int __init mfgpt_timer_setup(void);
 static inline int mfgpt_timer_setup(void) { return 0; }
 #endif
 
-#endif
+#endif /* ASM_X86__GEODE_H */
index c4c91b37c104810433f074c396ca3bbc0e69c701..497fb980d96245c72689ee3bd0eb630cf0c729a7 100644 (file)
@@ -53,4 +53,4 @@ static inline int irq_to_gpio(unsigned int irq)
 
 #endif /* CONFIG_GPIOLIB */
 
-#endif /* _ASM_I386_GPIO_H */
+#endif /* ASM_X86__GPIO_H */
index 4f85f0f4b5631699e21f36016bb88ebe9b51a911..700fe230d9190dba5237d838581ec58485f793a7 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_HARDIRQ_H
-#define __ASM_HARDIRQ_H
+#ifndef ASM_X86__HARDIRQ_32_H
+#define ASM_X86__HARDIRQ_32_H
 
 #include <linux/threads.h>
 #include <linux/irq.h>
@@ -25,4 +25,4 @@ DECLARE_PER_CPU(irq_cpustat_t, irq_stat);
 void ack_bad_irq(unsigned int irq);
 #include <linux/irq_cpustat.h>
 
-#endif /* __ASM_HARDIRQ_H */
+#endif /* ASM_X86__HARDIRQ_32_H */
index 95d5e090ed89eb48d80a6c8b679db973c059d701..f8bd2919a8ce88bcb98d6b7f24f51ecfda429fcd 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_HARDIRQ_H
-#define __ASM_HARDIRQ_H
+#ifndef ASM_X86__HARDIRQ_64_H
+#define ASM_X86__HARDIRQ_64_H
 
 #include <linux/threads.h>
 #include <linux/irq.h>
@@ -20,4 +20,4 @@
 
 extern void ack_bad_irq(unsigned int irq);
 
-#endif /* __ASM_HARDIRQ_H */
+#endif /* ASM_X86__HARDIRQ_64_H */
index 4514b16cc7236b447444b30caf26c1a75196f498..bc3f6a280316d5c33f41f9f48f70606e3f096021 100644 (file)
@@ -15,8 +15,8 @@
  * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
  */
 
-#ifndef _ASM_HIGHMEM_H
-#define _ASM_HIGHMEM_H
+#ifndef ASM_X86__HIGHMEM_H
+#define ASM_X86__HIGHMEM_H
 
 #ifdef __KERNEL__
 
@@ -79,4 +79,4 @@ extern void add_highpages_with_active_regions(int nid, unsigned long start_pfn,
 
 #endif /* __KERNEL__ */
 
-#endif /* _ASM_HIGHMEM_H */
+#endif /* ASM_X86__HIGHMEM_H */
index 82f1ac641bd73214115fe7baff23e35153cfd5f0..cbbbb6d4dd32bb838462864da48b26b1becbcd2d 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_X86_HPET_H
-#define ASM_X86_HPET_H
+#ifndef ASM_X86__HPET_H
+#define ASM_X86__HPET_H
 
 #ifdef CONFIG_HPET_TIMER
 
@@ -90,4 +90,4 @@ static inline int is_hpet_enabled(void) { return 0; }
 #define hpet_readl(a) 0
 
 #endif
-#endif /* ASM_X86_HPET_H */
+#endif /* ASM_X86__HPET_H */
index 439a9acc132d10f77b469fc24b250f3acc2f51d9..0b7ec5dc08840df634deb5151e35279500a49577 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_HUGETLB_H
-#define _ASM_X86_HUGETLB_H
+#ifndef ASM_X86__HUGETLB_H
+#define ASM_X86__HUGETLB_H
 
 #include <asm/page.h>
 
@@ -90,4 +90,4 @@ static inline void arch_release_hugepage(struct page *page)
 {
 }
 
-#endif /* _ASM_X86_HUGETLB_H */
+#endif /* ASM_X86__HUGETLB_H */
index edd0b95f14d0df6dd9b4f4cfb01d02548d485c9b..65997b15d56a4b03d3f0c035051d088c01b1931d 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_HW_IRQ_H
-#define _ASM_HW_IRQ_H
+#ifndef ASM_X86__HW_IRQ_H
+#define ASM_X86__HW_IRQ_H
 
 /*
  * (C) 1992, 1993 Linus Torvalds, (C) 1997 Ingo Molnar
@@ -93,6 +93,26 @@ extern asmlinkage void qic_reschedule_interrupt(void);
 extern asmlinkage void qic_enable_irq_interrupt(void);
 extern asmlinkage void qic_call_function_interrupt(void);
 
+/* SMP */
+extern void smp_apic_timer_interrupt(struct pt_regs *);
+#ifdef CONFIG_X86_32
+extern void smp_spurious_interrupt(struct pt_regs *);
+extern void smp_error_interrupt(struct pt_regs *);
+#else
+extern asmlinkage void smp_spurious_interrupt(void);
+extern asmlinkage void smp_error_interrupt(void);
+#endif
+#ifdef CONFIG_X86_SMP
+extern void smp_reschedule_interrupt(struct pt_regs *);
+extern void smp_call_function_interrupt(struct pt_regs *);
+extern void smp_call_function_single_interrupt(struct pt_regs *);
+#ifdef CONFIG_X86_32
+extern void smp_invalidate_interrupt(struct pt_regs *);
+#else
+extern asmlinkage void smp_invalidate_interrupt(struct pt_regs *);
+#endif
+#endif
+
 #ifdef CONFIG_X86_32
 extern void (*const interrupt[NR_IRQS])(void);
 #else
@@ -112,4 +132,4 @@ static inline void __setup_vector_irq(int cpu) {}
 
 #endif /* !ASSEMBLY_ */
 
-#endif
+#endif /* ASM_X86__HW_IRQ_H */
index d2bbd238b3e1718e261904d1a1fd14dbf6703175..cc011a3bc1c280a1b7fb44b8cce834100c675d37 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_HYPERTRANSPORT_H
-#define ASM_HYPERTRANSPORT_H
+#ifndef ASM_X86__HYPERTRANSPORT_H
+#define ASM_X86__HYPERTRANSPORT_H
 
 /*
  * Constants for x86 Hypertransport Interrupts.
@@ -42,4 +42,4 @@
 #define HT_IRQ_HIGH_DEST_ID(v)                                         \
        ((((v) >> 8) << HT_IRQ_HIGH_DEST_ID_SHIFT) & HT_IRQ_HIGH_DEST_ID_MASK)
 
-#endif /* ASM_HYPERTRANSPORT_H */
+#endif /* ASM_X86__HYPERTRANSPORT_H */
index 56d00e31aec0064856fb0c04a80df039b037a30b..1ecdc3ed96e4ecf156c83cae583ad2779d96f8b9 100644 (file)
@@ -7,8 +7,8 @@
  * x86-64 work by Andi Kleen 2002
  */
 
-#ifndef _ASM_X86_I387_H
-#define _ASM_X86_I387_H
+#ifndef ASM_X86__I387_H
+#define ASM_X86__I387_H
 
 #include <linux/sched.h>
 #include <linux/kernel_stat.h>
@@ -25,6 +25,7 @@ extern void mxcsr_feature_mask_init(void);
 extern int init_fpu(struct task_struct *child);
 extern asmlinkage void math_state_restore(void);
 extern void init_thread_xstate(void);
+extern int dump_fpu(struct pt_regs *, struct user_i387_struct *);
 
 extern user_regset_active_fn fpregs_active, xfpregs_active;
 extern user_regset_get_fn fpregs_get, xfpregs_get, fpregs_soft_get;
@@ -336,4 +337,4 @@ static inline unsigned short get_fpu_mxcsr(struct task_struct *tsk)
        }
 }
 
-#endif /* _ASM_X86_I387_H */
+#endif /* ASM_X86__I387_H */
index b51c0487fc41d6aec43c7db474e80abd0330d50d..15a5b530044e85a56361f29c38ffd7eb75d1b38e 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_I8253_H__
-#define __ASM_I8253_H__
+#ifndef ASM_X86__I8253_H
+#define ASM_X86__I8253_H
 
 /* i8253A PIT registers */
 #define PIT_MODE               0x43
@@ -15,4 +15,4 @@ extern void setup_pit_timer(void);
 #define inb_pit                inb_p
 #define outb_pit       outb_p
 
-#endif /* __ASM_I8253_H__ */
+#endif /* ASM_X86__I8253_H */
index 2f98df91f1f2bef9e7fc7bc47b3a42bbe14403d3..c586559a6957813187d9f4b8ecce0e14f35653a6 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_I8259_H__
-#define __ASM_I8259_H__
+#ifndef ASM_X86__I8259_H
+#define ASM_X86__I8259_H
 
 #include <linux/delay.h>
 
@@ -57,4 +57,4 @@ static inline void outb_pic(unsigned char value, unsigned int port)
 
 extern struct irq_chip i8259A_chip;
 
-#endif /* __ASM_I8259_H__ */
+#endif /* ASM_X86__I8259_H */
index 55d3abe5276f677c43b1840f3503c783b86217c8..f932f7ad51ddb1c11e6c121c2dd2021a60c8abf2 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_64_IA32_H
-#define _ASM_X86_64_IA32_H
+#ifndef ASM_X86__IA32_H
+#define ASM_X86__IA32_H
 
 
 #ifdef CONFIG_IA32_EMULATION
@@ -167,4 +167,4 @@ extern void ia32_pick_mmap_layout(struct mm_struct *mm);
 
 #endif /* !CONFIG_IA32_SUPPORT */
 
-#endif
+#endif /* ASM_X86__IA32_H */
index 61cea9e7c5c1b499dc67395b3d61ea18d54fee3f..dbd887d8a5a5846183fcd966feafbc73fedf3f2d 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_64_IA32_UNISTD_H_
-#define _ASM_X86_64_IA32_UNISTD_H_
+#ifndef ASM_X86__IA32_UNISTD_H
+#define ASM_X86__IA32_UNISTD_H
 
 /*
  * This file contains the system call numbers of the ia32 port,
@@ -15,4 +15,4 @@
 #define __NR_ia32_sigreturn    119
 #define __NR_ia32_rt_sigreturn 173
 
-#endif /* _ASM_X86_64_IA32_UNISTD_H_ */
+#endif /* ASM_X86__IA32_UNISTD_H */
index cbb649123612f003542c463ff99e54062653c306..baa3f783d27dcb58c1de4fa66eb5f31deaecc872 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_64_IDLE_H
-#define _ASM_X86_64_IDLE_H 1
+#ifndef ASM_X86__IDLE_H
+#define ASM_X86__IDLE_H
 
 #define IDLE_START 1
 #define IDLE_END 2
@@ -12,4 +12,4 @@ void exit_idle(void);
 
 void c1e_remove_cpu(int cpu);
 
-#endif
+#endif /* ASM_X86__IDLE_H */
index fa0fd068bc2e29aeaaad694db8c0e570c43c0df5..07c03c6c9a169cdb5eeeab1d840f1a61cef2052e 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_INTEL_ARCH_PERFMON_H
-#define _ASM_X86_INTEL_ARCH_PERFMON_H
+#ifndef ASM_X86__INTEL_ARCH_PERFMON_H
+#define ASM_X86__INTEL_ARCH_PERFMON_H
 
 #define MSR_ARCH_PERFMON_PERFCTR0              0xc1
 #define MSR_ARCH_PERFMON_PERFCTR1              0xc2
@@ -28,4 +28,4 @@ union cpuid10_eax {
        unsigned int full;
 };
 
-#endif /* _ASM_X86_INTEL_ARCH_PERFMON_H */
+#endif /* ASM_X86__INTEL_ARCH_PERFMON_H */
index 0f954dc89cb3c537ebb444e402987616b0a9714b..72b7719523bfa9f26efc333ed0efb160ad37d997 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_IO_H
-#define _ASM_X86_IO_H
+#ifndef ASM_X86__IO_H
+#define ASM_X86__IO_H
 
 #define ARCH_HAS_IOREMAP_WC
 
@@ -73,6 +73,8 @@ build_mmio_write(__writeq, "q", unsigned long, "r", )
 #define writeq writeq
 #endif
 
+extern int iommu_bio_merge;
+
 #ifdef CONFIG_X86_32
 # include "io_32.h"
 #else
@@ -99,4 +101,4 @@ extern void early_iounmap(void *addr, unsigned long size);
 extern void __iomem *fix_ioremap(unsigned idx, unsigned long phys);
 
 
-#endif /* _ASM_X86_IO_H */
+#endif /* ASM_X86__IO_H */
index e876d89ac15618f88ea4b624de64c6b1fc27e9cd..4f7d878bda1819a51541b67bda6dc7f4c53ac248 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_IO_H
-#define _ASM_IO_H
+#ifndef ASM_X86__IO_32_H
+#define ASM_X86__IO_32_H
 
 #include <linux/string.h>
 #include <linux/compiler.h>
@@ -281,4 +281,4 @@ BUILDIO(b, b, char)
 BUILDIO(w, w, short)
 BUILDIO(l, , int)
 
-#endif
+#endif /* ASM_X86__IO_32_H */
index 22995c5c5adc0d001bb40730fbeb15d47951ff01..64429e9431a8aef1089c25c8c00c18b64cd93663 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_IO_H
-#define _ASM_IO_H
+#ifndef ASM_X86__IO_64_H
+#define ASM_X86__IO_64_H
 
 
 /*
@@ -235,7 +235,6 @@ void memset_io(volatile void __iomem *a, int b, size_t c);
 
 #define flush_write_buffers()
 
-extern int iommu_bio_merge;
 #define BIO_VMERGE_BOUNDARY iommu_bio_merge
 
 /*
@@ -245,4 +244,4 @@ extern int iommu_bio_merge;
 
 #endif /* __KERNEL__ */
 
-#endif
+#endif /* ASM_X86__IO_64_H */
index 14f82bbcb5fd6ee5d09f05be363651258ff4e9bb..be62847ab07eaa8b5d779ed5b9b0f6316f89c383 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_IO_APIC_H
-#define __ASM_IO_APIC_H
+#ifndef ASM_X86__IO_APIC_H
+#define ASM_X86__IO_APIC_H
 
 #include <linux/types.h>
 #include <asm/mpspec.h>
@@ -189,4 +189,4 @@ static const int timer_through_8259 = 0;
 static inline void ioapic_init_mappings(void) { }
 #endif
 
-#endif
+#endif /* ASM_X86__IO_APIC_H */
index c0c338bd40682e41e4699639794a301a87a3b3ae..33660351239968bd22205ed9e4b45e674bc67e96 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_IOCTLS_H
-#define _ASM_X86_IOCTLS_H
+#ifndef ASM_X86__IOCTLS_H
+#define ASM_X86__IOCTLS_H
 
 #include <asm/ioctl.h>
 
@@ -85,4 +85,4 @@
 
 #define TIOCSER_TEMT    0x01   /* Transmitter physically empty */
 
-#endif
+#endif /* ASM_X86__IOCTLS_H */
index 5f888cc5be49a0eb87fab02d32ec050a686d0387..e86f44148c66f043cfb3a9ba9dfc1419cc2b25da 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X8664_IOMMU_H
-#define _ASM_X8664_IOMMU_H 1
+#ifndef ASM_X86__IOMMU_H
+#define ASM_X86__IOMMU_H
 
 extern void pci_iommu_shutdown(void);
 extern void no_iommu_init(void);
@@ -42,4 +42,4 @@ static inline void gart_iommu_hole_init(void)
 }
 #endif
 
-#endif
+#endif /* ASM_X86__IOMMU_H */
index ee678fd51594e5100d42e244433f3e8dc1c70690..910304fbdc8f289e7f92e37a4bd2089b540f585f 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_IPCBUF_H
-#define _ASM_X86_IPCBUF_H
+#ifndef ASM_X86__IPCBUF_H
+#define ASM_X86__IPCBUF_H
 
 /*
  * The ipc64_perm structure for x86 architecture.
@@ -25,4 +25,4 @@ struct ipc64_perm {
        unsigned long           __unused2;
 };
 
-#endif /* _ASM_X86_IPCBUF_H */
+#endif /* ASM_X86__IPCBUF_H */
index bb1c09f7a76ced4cd028d631d79a13d0171e8c2c..c1b2267975181fb18da479d464fdea9096b80591 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_IPI_H
-#define __ASM_IPI_H
+#ifndef ASM_X86__IPI_H
+#define ASM_X86__IPI_H
 
 /*
  * Copyright 2004 James Cleverdon, IBM.
@@ -129,4 +129,4 @@ static inline void send_IPI_mask_sequence(cpumask_t mask, int vector)
        local_irq_restore(flags);
 }
 
-#endif /* __ASM_IPI_H */
+#endif /* ASM_X86__IPI_H */
index 1a292575731745bdc9c5734adb426220eac6649c..1e5f2909c1db8c7db9330412444cafb07c0d1149 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_IRQ_H
-#define _ASM_IRQ_H
+#ifndef ASM_X86__IRQ_H
+#define ASM_X86__IRQ_H
 /*
  *     (C) 1992, 1993 Linus Torvalds, (C) 1997 Ingo Molnar
  *
@@ -47,4 +47,4 @@ extern void native_init_IRQ(void);
 /* Interrupt vector management */
 extern DECLARE_BITMAP(used_vectors, NR_VECTORS);
 
-#endif /* _ASM_IRQ_H */
+#endif /* ASM_X86__IRQ_H */
index 3368b20c0b489fa04b46070d53aecaaeb8dc01e0..316a3b2588715cd0cec869c51eaa4f6774972c64 100644 (file)
@@ -4,8 +4,8 @@
  *
  * Jeremy Fitzhardinge <jeremy@goop.org>
  */
-#ifndef _ASM_I386_IRQ_REGS_H
-#define _ASM_I386_IRQ_REGS_H
+#ifndef ASM_X86__IRQ_REGS_32_H
+#define ASM_X86__IRQ_REGS_32_H
 
 #include <asm/percpu.h>
 
@@ -26,4 +26,4 @@ static inline struct pt_regs *set_irq_regs(struct pt_regs *new_regs)
        return old_regs;
 }
 
-#endif /* _ASM_I386_IRQ_REGS_H */
+#endif /* ASM_X86__IRQ_REGS_32_H */
index a48c7f2dbdc04b32f010fbc6267b7a479f37e578..c5d2d767a1f356366e7ee57716ffd057ff3deb4a 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_IRQ_VECTORS_H
-#define _ASM_IRQ_VECTORS_H
+#ifndef ASM_X86__IRQ_VECTORS_H
+#define ASM_X86__IRQ_VECTORS_H
 
 #include <linux/threads.h>
 
 #define VIC_CPU_BOOT_ERRATA_CPI                (VIC_CPI_LEVEL0 + 8)
 
 
-#endif /* _ASM_IRQ_VECTORS_H */
+#endif /* ASM_X86__IRQ_VECTORS_H */
index 6ec6ceed95a718ec9d3c91f6004a459781dee74b..35a2fe9bc9212f799d3f3c2797af33d65b11eacd 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_IST_H
-#define _ASM_IST_H
+#ifndef ASM_X86__IST_H
+#define ASM_X86__IST_H
 
 /*
  * Include file for the interface to IST BIOS
@@ -31,4 +31,4 @@ struct ist_info {
 extern struct ist_info ist_info;
 
 #endif /* __KERNEL__ */
-#endif /* _ASM_IST_H */
+#endif /* ASM_X86__IST_H */
index 452e2b696ff48ef2cdf26175572dde1132a175cf..2bbaf4370a553b7aa6cff16b61c9f1f39e8b1009 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_K8_H
-#define _ASM_K8_H 1
+#ifndef ASM_X86__K8_H
+#define ASM_X86__K8_H
 
 #include <linux/pci.h>
 
@@ -12,4 +12,4 @@ extern int cache_k8_northbridges(void);
 extern void k8_flush_garts(void);
 extern int k8_scan_nodes(unsigned long start, unsigned long end);
 
-#endif
+#endif /* ASM_X86__K8_H */
index 96651bb59ba18c6f8506d985f9c98a757617a338..5ec3ad3e825c4dadfcbcff6b6f9c880f6ec02c7a 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_KDEBUG_H
-#define _ASM_X86_KDEBUG_H
+#ifndef ASM_X86__KDEBUG_H
+#define ASM_X86__KDEBUG_H
 
 #include <linux/notifier.h>
 
@@ -35,4 +35,4 @@ extern void show_regs(struct pt_regs *regs);
 extern unsigned long oops_begin(void);
 extern void oops_end(unsigned long, struct pt_regs *, int signr);
 
-#endif
+#endif /* ASM_X86__KDEBUG_H */
index 4246ab7dc9887b58e898569a6173eeb15d3437a9..ea09600d6129543392b09936962a873e4e2ac622 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _KEXEC_H
-#define _KEXEC_H
+#ifndef ASM_X86__KEXEC_H
+#define ASM_X86__KEXEC_H
 
 #ifdef CONFIG_X86_32
 # define PA_CONTROL_PAGE       0
@@ -172,4 +172,4 @@ relocate_kernel(unsigned long indirection_page,
 
 #endif /* __ASSEMBLY__ */
 
-#endif /* _KEXEC_H */
+#endif /* ASM_X86__KEXEC_H */
index 94d63db1036590d95e4666a2059877d6a54bc8d9..d283863354de7279ce915bb0905680991b1ec250 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_KGDB_H_
-#define _ASM_KGDB_H_
+#ifndef ASM_X86__KGDB_H
+#define ASM_X86__KGDB_H
 
 /*
  * Copyright (C) 2001-2004 Amit S. Kale
@@ -76,4 +76,4 @@ static inline void arch_kgdb_breakpoint(void)
 #define BREAK_INSTR_SIZE       1
 #define CACHE_FLUSH_IS_SAFE    1
 
-#endif                         /* _ASM_KGDB_H_ */
+#endif /* ASM_X86__KGDB_H */
index 5f4174132a222a34d453b2fb915a0993a6e923be..89f44493e6432ad192fa65faeac1b46c93ce6eb6 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_KMAP_TYPES_H
-#define _ASM_X86_KMAP_TYPES_H
+#ifndef ASM_X86__KMAP_TYPES_H
+#define ASM_X86__KMAP_TYPES_H
 
 #if defined(CONFIG_X86_32) && defined(CONFIG_DEBUG_HIGHMEM)
 # define D(n) __KM_FENCE_##n ,
@@ -26,4 +26,4 @@ D(13) KM_TYPE_NR
 
 #undef D
 
-#endif
+#endif /* ASM_X86__KMAP_TYPES_H */
index 54980b0b38925ade9c59799f906234e313b3237c..bd8407863c13127f1ed7ce1384fce4086e135022 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_KPROBES_H
-#define _ASM_KPROBES_H
+#ifndef ASM_X86__KPROBES_H
+#define ASM_X86__KPROBES_H
 /*
  *  Kernel Probes (KProbes)
  *
@@ -94,4 +94,4 @@ static inline void restore_interrupts(struct pt_regs *regs)
 extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
 extern int kprobe_exceptions_notify(struct notifier_block *self,
                                    unsigned long val, void *data);
-#endif                         /* _ASM_KPROBES_H */
+#endif /* ASM_X86__KPROBES_H */
index 6f1840812e595f05b7d5a064412e05d7e756b1cc..78e954db1e7f60066ea2cd232bf4d38a99821e57 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __LINUX_KVM_X86_H
-#define __LINUX_KVM_X86_H
+#ifndef ASM_X86__KVM_H
+#define ASM_X86__KVM_H
 
 /*
  * KVM x86 specific structures and definitions
@@ -230,4 +230,4 @@ struct kvm_pit_state {
 #define KVM_TRC_APIC_ACCESS      (KVM_TRC_HANDLER + 0x14)
 #define KVM_TRC_TDP_FAULT        (KVM_TRC_HANDLER + 0x15)
 
-#endif
+#endif /* ASM_X86__KVM_H */
index c2e34c27590066e4cf3359b78c1805d6c02805fc..69794547f514f5f249b65acf55ba8d5fd5c12685 100644 (file)
@@ -1,4 +1,4 @@
-#/*
+/*
  * Kernel-based Virtual Machine driver for Linux
  *
  * This header defines architecture specific interfaces, x86 version
@@ -8,8 +8,8 @@
  *
  */
 
-#ifndef ASM_KVM_HOST_H
-#define ASM_KVM_HOST_H
+#ifndef ASM_X86__KVM_HOST_H
+#define ASM_X86__KVM_HOST_H
 
 #include <linux/types.h>
 #include <linux/mm.h>
@@ -735,4 +735,4 @@ asmlinkage void kvm_handle_fault_on_reboot(void);
 int kvm_unmap_hva(struct kvm *kvm, unsigned long hva);
 int kvm_age_hva(struct kvm *kvm, unsigned long hva);
 
-#endif
+#endif /* ASM_X86__KVM_HOST_H */
index 76f392146daa46304adfb404874164a7a628010d..30054fded4fbbe325271e9ca2db0424eb3ebbdde 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __X86_KVM_PARA_H
-#define __X86_KVM_PARA_H
+#ifndef ASM_X86__KVM_PARA_H
+#define ASM_X86__KVM_PARA_H
 
 /* This CPUID returns the signature 'KVMKVMKVM' in ebx, ecx, and edx.  It
  * should be used to determine that a VM is running under KVM.
@@ -144,4 +144,4 @@ static inline unsigned int kvm_arch_para_features(void)
 
 #endif
 
-#endif
+#endif /* ASM_X86__KVM_PARA_H */
index 4e8c1e48d91daf5c8e73e9d3441a73e70539c000..e2d9b030c1ac9460297c34c08a1e796b13afa85c 100644 (file)
@@ -8,8 +8,8 @@
  * From: xen-unstable 10676:af9809f51f81a3c43f276f00c81a52ef558afda4
  */
 
-#ifndef __X86_EMULATE_H__
-#define __X86_EMULATE_H__
+#ifndef ASM_X86__KVM_X86_EMULATE_H
+#define ASM_X86__KVM_X86_EMULATE_H
 
 struct x86_emulate_ctxt;
 
@@ -181,4 +181,4 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt,
 int x86_emulate_insn(struct x86_emulate_ctxt *ctxt,
                     struct x86_emulate_ops *ops);
 
-#endif                         /* __X86_EMULATE_H__ */
+#endif /* ASM_X86__KVM_X86_EMULATE_H */
index 20c597242b53db0038fbf4efe7403b8425c7e16f..a5228504d867e68045b52f6a514b8f2130efacec 100644 (file)
@@ -3,8 +3,8 @@
  *
  * Definitions of structures used with the modify_ldt system call.
  */
-#ifndef _ASM_X86_LDT_H
-#define _ASM_X86_LDT_H
+#ifndef ASM_X86__LDT_H
+#define ASM_X86__LDT_H
 
 /* Maximum number of LDT entries supported. */
 #define LDT_ENTRIES    8192
@@ -37,4 +37,4 @@ struct user_desc {
 #define MODIFY_LDT_CONTENTS_CODE       2
 
 #endif /* !__ASSEMBLY__ */
-#endif
+#endif /* ASM_X86__LDT_H */
index be4a7247fa2b3ea44c07332bf76436d0cb6cc7df..7505e947ed2719a32a91c53a52598905a63818e4 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _X86_LGUEST_H
-#define _X86_LGUEST_H
+#ifndef ASM_X86__LGUEST_H
+#define ASM_X86__LGUEST_H
 
 #define GDT_ENTRY_LGUEST_CS    10
 #define GDT_ENTRY_LGUEST_DS    11
@@ -91,4 +91,4 @@ static inline void lguest_set_ts(void)
 
 #endif /* __ASSEMBLY__ */
 
-#endif
+#endif /* ASM_X86__LGUEST_H */
index a3241f28e34a51e469c77251200915567c8ade42..8f034ba4b53ebf1b3e6df32be9e5252ccf433f76 100644 (file)
@@ -1,6 +1,6 @@
 /* Architecture specific portion of the lguest hypercalls */
-#ifndef _X86_LGUEST_HCALL_H
-#define _X86_LGUEST_HCALL_H
+#ifndef ASM_X86__LGUEST_HCALL_H
+#define ASM_X86__LGUEST_HCALL_H
 
 #define LHCALL_FLUSH_ASYNC     0
 #define LHCALL_LGUEST_INIT     1
@@ -68,4 +68,4 @@ struct hcall_args {
 };
 
 #endif /* !__ASSEMBLY__ */
-#endif /* _I386_LGUEST_HCALL_H */
+#endif /* ASM_X86__LGUEST_HCALL_H */
index 64e444f8e85b2d9fccaf50cc78ceaa1da0654877..42d8b62ee8abe72e842c55a3c337d0e947802561 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_LINKAGE_H
-#define __ASM_LINKAGE_H
+#ifndef ASM_X86__LINKAGE_H
+#define ASM_X86__LINKAGE_H
 
 #undef notrace
 #define notrace __attribute__((no_instrument_function))
@@ -57,5 +57,5 @@
 #define __ALIGN_STR ".align 16,0x90"
 #endif
 
-#endif
+#endif /* ASM_X86__LINKAGE_H */
 
index 330a72496abd94f9eb85cce30f8ae590b1b57e18..ae91994fd6c91dc607251a31d5e2df0db6d8f6af 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ARCH_LOCAL_H
-#define _ARCH_LOCAL_H
+#ifndef ASM_X86__LOCAL_H
+#define ASM_X86__LOCAL_H
 
 #include <linux/percpu.h>
 
@@ -232,4 +232,4 @@ static inline long local_sub_return(long i, local_t *l)
 #define __cpu_local_add(i, l)  cpu_local_add((i), (l))
 #define __cpu_local_sub(i, l)  cpu_local_sub((i), (l))
 
-#endif /* _ARCH_LOCAL_H */
+#endif /* ASM_X86__LOCAL_H */
index c3b9dc6970c95726a3adaafe5502334b9d64c68c..05362d44a3ee58f6f43b9eba015b9d3809a0ec88 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_MACH_APIC_H
-#define __ASM_MACH_APIC_H
+#ifndef ASM_X86__MACH_BIGSMP__MACH_APIC_H
+#define ASM_X86__MACH_BIGSMP__MACH_APIC_H
 
 #define xapic_phys_to_log_apicid(cpu) (per_cpu(x86_bios_cpu_apicid, cpu))
 #define esr_disable (1)
@@ -141,4 +141,4 @@ static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
        return cpuid_apic >> index_msb;
 }
 
-#endif /* __ASM_MACH_APIC_H */
+#endif /* ASM_X86__MACH_BIGSMP__MACH_APIC_H */
index a58ab5a75c8c57c5743a15f4f0fc1587f182a492..811935d9d49b6d17d625fecd1731ebc9fb947335 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_MACH_APICDEF_H
-#define __ASM_MACH_APICDEF_H
+#ifndef ASM_X86__MACH_BIGSMP__MACH_APICDEF_H
+#define ASM_X86__MACH_BIGSMP__MACH_APICDEF_H
 
 #define                APIC_ID_MASK            (0xFF<<24)
 
@@ -10,4 +10,4 @@ static inline unsigned get_apic_id(unsigned long x)
 
 #define                GET_APIC_ID(x)  get_apic_id(x)
 
-#endif
+#endif /* ASM_X86__MACH_BIGSMP__MACH_APICDEF_H */
index 9404c535b7ecbbf6f496d0cd80f4eb266a529208..b1b0f966a0099105573742db4e5ee47e94bfedc7 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_MACH_IPI_H
-#define __ASM_MACH_IPI_H
+#ifndef ASM_X86__MACH_BIGSMP__MACH_IPI_H
+#define ASM_X86__MACH_BIGSMP__MACH_IPI_H
 
 void send_IPI_mask_sequence(cpumask_t mask, int vector);
 
@@ -22,4 +22,4 @@ static inline void send_IPI_all(int vector)
        send_IPI_mask(cpu_online_map, vector);
 }
 
-#endif /* __ASM_MACH_IPI_H */
+#endif /* ASM_X86__MACH_BIGSMP__MACH_IPI_H */
index 989f34c37d321249f838efe86d4e9c2086b42233..2aa61b54fbd576f7c353eb4738904694e0844633 100644 (file)
@@ -3,8 +3,8 @@
  *  Split out from apm.c by Osamu Tomita <tomita@cinet.co.jp>
  */
 
-#ifndef _ASM_APM_H
-#define _ASM_APM_H
+#ifndef ASM_X86__MACH_DEFAULT__APM_H
+#define ASM_X86__MACH_DEFAULT__APM_H
 
 #ifdef APM_ZERO_SEGS
 #      define APM_DO_ZERO_SEGS \
@@ -70,4 +70,4 @@ static inline u8 apm_bios_call_simple_asm(u32 func, u32 ebx_in,
        return error;
 }
 
-#endif /* _ASM_APM_H */
+#endif /* ASM_X86__MACH_DEFAULT__APM_H */
index f3226b9a6b823459935a4de2c5b8e82165776e57..b615f40736be123e56a959aca3e7867a925162c7 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_MACH_APIC_H
-#define __ASM_MACH_APIC_H
+#ifndef ASM_X86__MACH_DEFAULT__MACH_APIC_H
+#define ASM_X86__MACH_DEFAULT__MACH_APIC_H
 
 #ifdef CONFIG_X86_LOCAL_APIC
 
@@ -138,4 +138,4 @@ static inline void enable_apic_mode(void)
 }
 
 #endif /* CONFIG_X86_LOCAL_APIC */
-#endif /* __ASM_MACH_APIC_H */
+#endif /* ASM_X86__MACH_DEFAULT__MACH_APIC_H */
index e4b29ba37de604894bae11681a9236bd64c041e7..936704f816d688601713d3e1998f8226bb1fb03b 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_MACH_APICDEF_H
-#define __ASM_MACH_APICDEF_H
+#ifndef ASM_X86__MACH_DEFAULT__MACH_APICDEF_H
+#define ASM_X86__MACH_DEFAULT__MACH_APICDEF_H
 
 #include <asm/apic.h>
 
@@ -21,4 +21,4 @@ static inline unsigned get_apic_id(unsigned long x)
 #define                GET_APIC_ID(x)  get_apic_id(x)
 #endif
 
-#endif
+#endif /* ASM_X86__MACH_DEFAULT__MACH_APICDEF_H */
index be323364e68f6d7522194f7b2d2941df8edd6d19..674bc7e50c356250348c5341a6aba2a9167920a1 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_MACH_IPI_H
-#define __ASM_MACH_IPI_H
+#ifndef ASM_X86__MACH_DEFAULT__MACH_IPI_H
+#define ASM_X86__MACH_DEFAULT__MACH_IPI_H
 
 /* Avoid include hell */
 #define NMI_VECTOR 0x02
@@ -61,4 +61,4 @@ static inline void send_IPI_all(int vector)
 }
 #endif
 
-#endif /* __ASM_MACH_IPI_H */
+#endif /* ASM_X86__MACH_DEFAULT__MACH_IPI_H */
index d14108505bb8905401f61ddab7f93fd34c3ce533..9c381f2815acb9752359d1538e662ff2966bc50f 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_MACH_MPPARSE_H
-#define __ASM_MACH_MPPARSE_H
+#ifndef ASM_X86__MACH_DEFAULT__MACH_MPPARSE_H
+#define ASM_X86__MACH_DEFAULT__MACH_MPPARSE_H
 
 static inline int mps_oem_check(struct mp_config_table *mpc, char *oem, 
                char *productid)
@@ -14,4 +14,4 @@ static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 }
 
 
-#endif /* __ASM_MACH_MPPARSE_H */
+#endif /* ASM_X86__MACH_DEFAULT__MACH_MPPARSE_H */
index 51c9a977593289a2c72452a0b2a44504a7353189..d77646f011f1bb1dfce06bce8b63732898490804 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_MACH_MPSPEC_H
-#define __ASM_MACH_MPSPEC_H
+#ifndef ASM_X86__MACH_DEFAULT__MACH_MPSPEC_H
+#define ASM_X86__MACH_DEFAULT__MACH_MPSPEC_H
 
 #define MAX_IRQ_SOURCES 256
 
@@ -9,4 +9,4 @@
 #define MAX_MP_BUSSES 32
 #endif
 
-#endif /* __ASM_MACH_MPSPEC_H */
+#endif /* ASM_X86__MACH_DEFAULT__MACH_MPSPEC_H */
index 4b76e536cd986307b071c8c11d2bff4c30b4112f..990b15833834bf861ceef35d810d4adaa899a84d 100644 (file)
@@ -10,8 +10,8 @@
  * directly because of the awkward 8-bit access mechanism of the 82C54
  * device.
  */
-#ifndef _MACH_TIMER_H
-#define _MACH_TIMER_H
+#ifndef ASM_X86__MACH_DEFAULT__MACH_TIMER_H
+#define ASM_X86__MACH_DEFAULT__MACH_TIMER_H
 
 #define CALIBRATE_TIME_MSEC 30 /* 30 msecs */
 #define CALIBRATE_LATCH        \
@@ -45,4 +45,4 @@ static inline void mach_countup(unsigned long *count_p)
        *count_p = count;
 }
 
-#endif /* !_MACH_TIMER_H */
+#endif /* ASM_X86__MACH_DEFAULT__MACH_TIMER_H */
index 2fe7705c0484ed074a5d0b2f9e2bf7acc88cd7cf..de9ac3f5c4ce547c2a204cac41c4010da2839fe7 100644 (file)
@@ -2,8 +2,8 @@
  *  Machine specific NMI handling for generic.
  *  Split out from traps.c by Osamu Tomita <tomita@cinet.co.jp>
  */
-#ifndef _MACH_TRAPS_H
-#define _MACH_TRAPS_H
+#ifndef ASM_X86__MACH_DEFAULT__MACH_TRAPS_H
+#define ASM_X86__MACH_DEFAULT__MACH_TRAPS_H
 
 #include <asm/mc146818rtc.h>
 
@@ -36,4 +36,4 @@ static inline void reassert_nmi(void)
                unlock_cmos();
 }
 
-#endif /* !_MACH_TRAPS_H */
+#endif /* ASM_X86__MACH_DEFAULT__MACH_TRAPS_H */
index 3ebb17893aa524d49d4bcdec543148ee7e72a326..361b810f5160a2e5a02e8ea66c365a9dc0abd0f1 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_MACH_WAKECPU_H
-#define __ASM_MACH_WAKECPU_H
+#ifndef ASM_X86__MACH_DEFAULT__MACH_WAKECPU_H
+#define ASM_X86__MACH_DEFAULT__MACH_WAKECPU_H
 
 /* 
  * This file copes with machines that wakeup secondary CPUs by the
@@ -39,4 +39,4 @@ static inline void restore_NMI_vector(unsigned short *high, unsigned short *low)
  #define inquire_remote_apic(apicid) {}
 #endif
 
-#endif /* __ASM_MACH_WAKECPU_H */
+#endif /* ASM_X86__MACH_DEFAULT__MACH_WAKECPU_H */
index 0a3fdf93067253e448ffa6a39ca8bcc0d1c0ed90..c1f6f682d61907ece9e20f19d25c59f019e436fc 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_MACH_APIC_H
-#define __ASM_MACH_APIC_H
+#ifndef ASM_X86__MACH_ES7000__MACH_APIC_H
+#define ASM_X86__MACH_ES7000__MACH_APIC_H
 
 #define xapic_phys_to_log_apicid(cpu) per_cpu(x86_bios_cpu_apicid, cpu)
 #define esr_disable (1)
@@ -191,4 +191,4 @@ static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
        return cpuid_apic >> index_msb;
 }
 
-#endif /* __ASM_MACH_APIC_H */
+#endif /* ASM_X86__MACH_ES7000__MACH_APIC_H */
index a58ab5a75c8c57c5743a15f4f0fc1587f182a492..a07e56744028b4f9ff327934448f0099ea7b85ef 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_MACH_APICDEF_H
-#define __ASM_MACH_APICDEF_H
+#ifndef ASM_X86__MACH_ES7000__MACH_APICDEF_H
+#define ASM_X86__MACH_ES7000__MACH_APICDEF_H
 
 #define                APIC_ID_MASK            (0xFF<<24)
 
@@ -10,4 +10,4 @@ static inline unsigned get_apic_id(unsigned long x)
 
 #define                GET_APIC_ID(x)  get_apic_id(x)
 
-#endif
+#endif /* ASM_X86__MACH_ES7000__MACH_APICDEF_H */
index 5e61bd220b06c3b8b5f0a816c02d5ecc592e7145..3a21240e03dc6fba203762e764af4675749175ee 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_MACH_IPI_H
-#define __ASM_MACH_IPI_H
+#ifndef ASM_X86__MACH_ES7000__MACH_IPI_H
+#define ASM_X86__MACH_ES7000__MACH_IPI_H
 
 void send_IPI_mask_sequence(cpumask_t mask, int vector);
 
@@ -21,4 +21,4 @@ static inline void send_IPI_all(int vector)
        send_IPI_mask(cpu_online_map, vector);
 }
 
-#endif /* __ASM_MACH_IPI_H */
+#endif /* ASM_X86__MACH_ES7000__MACH_IPI_H */
index ef26d3523625451c38eeaded73228869cf737a2b..befde24705b7b91bc631f7ca06d1403095f0a642 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_MACH_MPPARSE_H
-#define __ASM_MACH_MPPARSE_H
+#ifndef ASM_X86__MACH_ES7000__MACH_MPPARSE_H
+#define ASM_X86__MACH_ES7000__MACH_MPPARSE_H
 
 #include <linux/acpi.h>
 
@@ -26,4 +26,4 @@ static inline int es7000_check_dsdt(void)
 }
 #endif
 
-#endif /* __ASM_MACH_MPPARSE_H */
+#endif /* ASM_X86__MACH_ES7000__MACH_MPPARSE_H */
index 84ff58314501cfa3c83cf4a7024ad19ec00f9fa9..97c776ce13f2c11396c75ac1410196d49a321007 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_MACH_WAKECPU_H
-#define __ASM_MACH_WAKECPU_H
+#ifndef ASM_X86__MACH_ES7000__MACH_WAKECPU_H
+#define ASM_X86__MACH_ES7000__MACH_WAKECPU_H
 
 /* 
  * This file copes with machines that wakeup secondary CPUs by the
@@ -56,4 +56,4 @@ static inline void restore_NMI_vector(unsigned short *high, unsigned short *low)
  #define inquire_remote_apic(apicid) {}
 #endif
 
-#endif /* __ASM_MACH_WAKECPU_H */
+#endif /* ASM_X86__MACH_ES7000__MACH_WAKECPU_H */
index 5305dcb96df270f511ce44bd953fc62e2c15e489..6ce0f7786ef8bebfe8ef51414de7553c908a6fd7 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_MACH_GENERIC_GPIO_H
-#define __ASM_MACH_GENERIC_GPIO_H
+#ifndef ASM_X86__MACH_GENERIC__GPIO_H
+#define ASM_X86__MACH_GENERIC__GPIO_H
 
 int gpio_request(unsigned gpio, const char *label);
 void gpio_free(unsigned gpio);
@@ -12,4 +12,4 @@ int irq_to_gpio(unsigned irq);
 
 #include <asm-generic/gpio.h>           /* cansleep wrappers */
 
-#endif /* __ASM_MACH_GENERIC_GPIO_H */
+#endif /* ASM_X86__MACH_GENERIC__GPIO_H */
index 890ce3f5e09a7fbd89590fc7490627b0a807f986..f7870e1a220d535bbccd798dd994506c095aabe4 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_IRQ_VECTORS_LIMITS_H
-#define _ASM_IRQ_VECTORS_LIMITS_H
+#ifndef ASM_X86__MACH_GENERIC__IRQ_VECTORS_LIMITS_H
+#define ASM_X86__MACH_GENERIC__IRQ_VECTORS_LIMITS_H
 
 /*
  * For Summit or generic (i.e. installer) kernels, we have lots of I/O APICs,
@@ -11,4 +11,4 @@
 #define NR_IRQS        224
 #define NR_IRQ_VECTORS 1024
 
-#endif /* _ASM_IRQ_VECTORS_LIMITS_H */
+#endif /* ASM_X86__MACH_GENERIC__IRQ_VECTORS_LIMITS_H */
index 6eff343e12338f892693fa667ea25105f2ff7da9..5d010c6881dddc51bb9ad2a59503c79ad2837b14 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_MACH_APIC_H
-#define __ASM_MACH_APIC_H
+#ifndef ASM_X86__MACH_GENERIC__MACH_APIC_H
+#define ASM_X86__MACH_GENERIC__MACH_APIC_H
 
 #include <asm/genapic.h>
 
@@ -29,4 +29,4 @@
 
 extern void generic_bigsmp_probe(void);
 
-#endif /* __ASM_MACH_APIC_H */
+#endif /* ASM_X86__MACH_GENERIC__MACH_APIC_H */
index 28ed98972ca84a98fbdd2a38dceb8dbdb94e5ca9..1657f38b8f27e184bb930a24eb3b992eaf548bbb 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _GENAPIC_MACH_APICDEF_H
-#define _GENAPIC_MACH_APICDEF_H 1
+#ifndef ASM_X86__MACH_GENERIC__MACH_APICDEF_H
+#define ASM_X86__MACH_GENERIC__MACH_APICDEF_H
 
 #ifndef APIC_DEFINITION
 #include <asm/genapic.h>
@@ -8,4 +8,4 @@
 #define APIC_ID_MASK (genapic->apic_id_mask)
 #endif
 
-#endif
+#endif /* ASM_X86__MACH_GENERIC__MACH_APICDEF_H */
index 441b0fe3ed1d8142cb0ef503b5a58718f90b8137..f67433dbd65f9f85b549ee4e34efdf68385725f3 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _MACH_IPI_H
-#define _MACH_IPI_H 1
+#ifndef ASM_X86__MACH_GENERIC__MACH_IPI_H
+#define ASM_X86__MACH_GENERIC__MACH_IPI_H
 
 #include <asm/genapic.h>
 
@@ -7,4 +7,4 @@
 #define send_IPI_allbutself (genapic->send_IPI_allbutself)
 #define send_IPI_all (genapic->send_IPI_all)
 
-#endif
+#endif /* ASM_X86__MACH_GENERIC__MACH_IPI_H */
index 586cadbf3787ce9c98449921db1c14c942d418bc..3115564e557cfd6d6b25f6ea02bb585d17121e43 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _MACH_MPPARSE_H
-#define _MACH_MPPARSE_H 1
+#ifndef ASM_X86__MACH_GENERIC__MACH_MPPARSE_H
+#define ASM_X86__MACH_GENERIC__MACH_MPPARSE_H
 
 
 extern int mps_oem_check(struct mp_config_table *mpc, char *oem,
@@ -7,4 +7,4 @@ extern int mps_oem_check(struct mp_config_table *mpc, char *oem,
 
 extern int acpi_madt_oem_check(char *oem_id, char *oem_table_id);
 
-#endif
+#endif /* ASM_X86__MACH_GENERIC__MACH_MPPARSE_H */
index c83c120be538504f5139228bc53182e3040f43ea..6061b153613e32ec75d0cf983091aa13dbea31d5 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_MACH_MPSPEC_H
-#define __ASM_MACH_MPSPEC_H
+#ifndef ASM_X86__MACH_GENERIC__MACH_MPSPEC_H
+#define ASM_X86__MACH_GENERIC__MACH_MPSPEC_H
 
 #define MAX_IRQ_SOURCES 256
 
@@ -9,4 +9,4 @@
 
 extern void numaq_mps_oem_check(struct mp_config_table *mpc, char *oem,
                                char *productid);
-#endif /* __ASM_MACH_MPSPEC_H */
+#endif /* ASM_X86__MACH_GENERIC__MACH_MPSPEC_H */
index d802465e026a4a5adb6834f90c0ea74caa672617..7a0d39edfcfa628151c94947340eab6ef648aaf9 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_MACH_APIC_H
-#define __ASM_MACH_APIC_H
+#ifndef ASM_X86__MACH_NUMAQ__MACH_APIC_H
+#define ASM_X86__MACH_NUMAQ__MACH_APIC_H
 
 #include <asm/io.h>
 #include <linux/mmzone.h>
@@ -135,4 +135,4 @@ static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
        return cpuid_apic >> index_msb;
 }
 
-#endif /* __ASM_MACH_APIC_H */
+#endif /* ASM_X86__MACH_NUMAQ__MACH_APIC_H */
index bf439d0690f54e0c74a7fdf70c9a1cbf900d691d..f870ec5f77822d2358fec94b65e6c8650219037b 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_MACH_APICDEF_H
-#define __ASM_MACH_APICDEF_H
+#ifndef ASM_X86__MACH_NUMAQ__MACH_APICDEF_H
+#define ASM_X86__MACH_NUMAQ__MACH_APICDEF_H
 
 
 #define APIC_ID_MASK (0xF<<24)
@@ -11,4 +11,4 @@ static inline unsigned get_apic_id(unsigned long x)
 
 #define         GET_APIC_ID(x)  get_apic_id(x)
 
-#endif
+#endif /* ASM_X86__MACH_NUMAQ__MACH_APICDEF_H */
index c6044488e9e6085a971c7a59640a56adefe22d7b..1e835823f4bc6f88fa89292b72af44859f464ad1 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_MACH_IPI_H
-#define __ASM_MACH_IPI_H
+#ifndef ASM_X86__MACH_NUMAQ__MACH_IPI_H
+#define ASM_X86__MACH_NUMAQ__MACH_IPI_H
 
 void send_IPI_mask_sequence(cpumask_t, int vector);
 
@@ -22,4 +22,4 @@ static inline void send_IPI_all(int vector)
        send_IPI_mask(cpu_online_map, vector);
 }
 
-#endif /* __ASM_MACH_IPI_H */
+#endif /* ASM_X86__MACH_NUMAQ__MACH_IPI_H */
index 626aef6b155f1498eee4ab3594eab6a4adeee00d..74ade184920b0be727db25d2e2802ca17ec17aeb 100644 (file)
@@ -1,7 +1,7 @@
-#ifndef __ASM_MACH_MPPARSE_H
-#define __ASM_MACH_MPPARSE_H
+#ifndef ASM_X86__MACH_NUMAQ__MACH_MPPARSE_H
+#define ASM_X86__MACH_NUMAQ__MACH_MPPARSE_H
 
 extern void numaq_mps_oem_check(struct mp_config_table *mpc, char *oem,
                                char *productid);
 
-#endif /* __ASM_MACH_MPPARSE_H */
+#endif /* ASM_X86__MACH_NUMAQ__MACH_MPPARSE_H */
index 00530041a991569f35e0da1fdd298bd96b8e6786..0db8cea643c02ba346085f92d42c5bfbc56419c1 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_MACH_WAKECPU_H
-#define __ASM_MACH_WAKECPU_H
+#ifndef ASM_X86__MACH_NUMAQ__MACH_WAKECPU_H
+#define ASM_X86__MACH_NUMAQ__MACH_WAKECPU_H
 
 /* This file copes with machines that wakeup secondary CPUs by NMIs */
 
@@ -40,4 +40,4 @@ static inline void restore_NMI_vector(unsigned short *high, unsigned short *low)
 
 #define inquire_remote_apic(apicid) {}
 
-#endif /* __ASM_MACH_WAKECPU_H */
+#endif /* ASM_X86__MACH_NUMAQ__MACH_WAKECPU_H */
index acce0b7d397bb2465ee89beb6e8a7d817bccbc7a..94b6cdf532e207f210fffa131dfd34e2fa82e414 100644 (file)
@@ -1,5 +1,7 @@
-#ifndef _RDC321X_GPIO_H
-#define _RDC321X_GPIO_H
+#ifndef ASM_X86__MACH_RDC321X__GPIO_H
+#define ASM_X86__MACH_RDC321X__GPIO_H
+
+#include <linux/kernel.h>
 
 extern int rdc_gpio_get_value(unsigned gpio);
 extern void rdc_gpio_set_value(unsigned gpio, int value);
@@ -18,6 +20,7 @@ static inline int gpio_request(unsigned gpio, const char *label)
 
 static inline void gpio_free(unsigned gpio)
 {
+       might_sleep();
        rdc_gpio_free(gpio);
 }
 
@@ -54,4 +57,4 @@ static inline int irq_to_gpio(unsigned irq)
 /* For cansleep */
 #include <asm-generic/gpio.h>
 
-#endif /* _RDC321X_GPIO_H_ */
+#endif /* ASM_X86__MACH_RDC321X__GPIO_H */
index 890ce3f5e09a7fbd89590fc7490627b0a807f986..22f376ad68e184fa3d3c517914a27a0958f9b628 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_IRQ_VECTORS_LIMITS_H
-#define _ASM_IRQ_VECTORS_LIMITS_H
+#ifndef ASM_X86__MACH_SUMMIT__IRQ_VECTORS_LIMITS_H
+#define ASM_X86__MACH_SUMMIT__IRQ_VECTORS_LIMITS_H
 
 /*
  * For Summit or generic (i.e. installer) kernels, we have lots of I/O APICs,
@@ -11,4 +11,4 @@
 #define NR_IRQS        224
 #define NR_IRQ_VECTORS 1024
 
-#endif /* _ASM_IRQ_VECTORS_LIMITS_H */
+#endif /* ASM_X86__MACH_SUMMIT__IRQ_VECTORS_LIMITS_H */
index c47e2ab5c5ca06515c87b7a320e42fccff3e8ed2..7a66758d701d858fc6373c505d2076a698dc41b6 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_MACH_APIC_H
-#define __ASM_MACH_APIC_H
+#ifndef ASM_X86__MACH_SUMMIT__MACH_APIC_H
+#define ASM_X86__MACH_SUMMIT__MACH_APIC_H
 
 #include <asm/smp.h>
 
@@ -182,4 +182,4 @@ static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
        return hard_smp_processor_id() >> index_msb;
 }
 
-#endif /* __ASM_MACH_APIC_H */
+#endif /* ASM_X86__MACH_SUMMIT__MACH_APIC_H */
index a58ab5a75c8c57c5743a15f4f0fc1587f182a492..d4bc8590c4f64f1ee96f59fc4159931dad5bfe9f 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_MACH_APICDEF_H
-#define __ASM_MACH_APICDEF_H
+#ifndef ASM_X86__MACH_SUMMIT__MACH_APICDEF_H
+#define ASM_X86__MACH_SUMMIT__MACH_APICDEF_H
 
 #define                APIC_ID_MASK            (0xFF<<24)
 
@@ -10,4 +10,4 @@ static inline unsigned get_apic_id(unsigned long x)
 
 #define                GET_APIC_ID(x)  get_apic_id(x)
 
-#endif
+#endif /* ASM_X86__MACH_SUMMIT__MACH_APICDEF_H */
index 9404c535b7ecbbf6f496d0cd80f4eb266a529208..a3b31c528d9082ae463396c3d5dcd6c203683256 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_MACH_IPI_H
-#define __ASM_MACH_IPI_H
+#ifndef ASM_X86__MACH_SUMMIT__MACH_IPI_H
+#define ASM_X86__MACH_SUMMIT__MACH_IPI_H
 
 void send_IPI_mask_sequence(cpumask_t mask, int vector);
 
@@ -22,4 +22,4 @@ static inline void send_IPI_all(int vector)
        send_IPI_mask(cpu_online_map, vector);
 }
 
-#endif /* __ASM_MACH_IPI_H */
+#endif /* ASM_X86__MACH_SUMMIT__MACH_IPI_H */
index fdf5917013399d9175253ddf587e440c2caea654..92396f28772b9ef302e909f4d45f6fc678949ac6 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_MACH_MPPARSE_H
-#define __ASM_MACH_MPPARSE_H
+#ifndef ASM_X86__MACH_SUMMIT__MACH_MPPARSE_H
+#define ASM_X86__MACH_SUMMIT__MACH_MPPARSE_H
 
 #include <mach_apic.h>
 #include <asm/tsc.h>
@@ -107,4 +107,4 @@ static inline int is_WPEG(struct rio_detail *rio){
                rio->type == LookOutAWPEG || rio->type == LookOutBWPEG);
 }
 
-#endif /* __ASM_MACH_MPPARSE_H */
+#endif /* ASM_X86__MACH_SUMMIT__MACH_MPPARSE_H */
index 9bf4ae93ab10b3a549efaac717fcdce0f81a158d..5768d8e95c8c2b671ffb93383d13dd842a696208 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _I386_MATH_EMU_H
-#define _I386_MATH_EMU_H
+#ifndef ASM_X86__MATH_EMU_H
+#define ASM_X86__MATH_EMU_H
 
 /* This structure matches the layout of the data saved to the stack
    following a device-not-present interrupt, part of it saved
@@ -28,4 +28,4 @@ struct info {
        long ___vm86_fs;
        long ___vm86_gs;
 };
-#endif
+#endif /* ASM_X86__MATH_EMU_H */
index daf1ccde77af32a855d21112693fd0b9e6d126e2..a995f33176cd026f60f21c18008811f9a5a996a4 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Machine dependent access functions for RTC registers.
  */
-#ifndef _ASM_MC146818RTC_H
-#define _ASM_MC146818RTC_H
+#ifndef ASM_X86__MC146818RTC_H
+#define ASM_X86__MC146818RTC_H
 
 #include <asm/io.h>
 #include <asm/system.h>
@@ -101,4 +101,4 @@ extern unsigned long mach_get_cmos_time(void);
 
 #define RTC_IRQ 8
 
-#endif /* _ASM_MC146818RTC_H */
+#endif /* ASM_X86__MC146818RTC_H */
index 09adf2eac4dce0517ea1b3b9c7c5173415fb6ff5..60d1ed287b1301c2907e910ab4c7c0e182df87bd 100644 (file)
@@ -1,8 +1,8 @@
 /* -*- mode: c; c-basic-offset: 8 -*- */
 
 /* Platform specific MCA defines */
-#ifndef _ASM_MCA_H
-#define _ASM_MCA_H
+#ifndef ASM_X86__MCA_H
+#define ASM_X86__MCA_H
 
 /* Maximal number of MCA slots - actually, some machines have less, but
  * they all have sufficient number of POS registers to cover 8.
@@ -40,4 +40,4 @@
  */
 #define MCA_NUMADAPTERS (MCA_MAX_SLOT_NR+3)
 
-#endif
+#endif /* ASM_X86__MCA_H */
index c3dca6edc6b1b82c3a252c4b005abc77106100d8..49f22be237d29c0e76e520d33b1fdb654f8a3d5d 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef MCA_DMA_H
-#define MCA_DMA_H
+#ifndef ASM_X86__MCA_DMA_H
+#define ASM_X86__MCA_DMA_H
 
 #include <asm/io.h>
 #include <linux/ioport.h>
@@ -198,4 +198,4 @@ static inline void mca_set_dma_mode(unsigned int dmanr, unsigned int mode)
        outb(mode, MCA_DMA_REG_EXE);
 }
 
-#endif /* MCA_DMA_H */
+#endif /* ASM_X86__MCA_DMA_H */
index 531eaa587455a90c2274ef5f5491e8214dd51ccf..036133eaf7448e4625a713bab4b9ff3f53e98bb2 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_MCE_H
-#define _ASM_X86_MCE_H
+#ifndef ASM_X86__MCE_H
+#define ASM_X86__MCE_H
 
 #ifdef __x86_64__
 
@@ -127,4 +127,4 @@ extern void restart_mce(void);
 
 #endif /* __KERNEL__ */
 
-#endif
+#endif /* ASM_X86__MCE_H */
index 90bc4108a4fdf917fc243502bd7fcf833f482a55..4ef28e6de3837e38db2bd98a2af0116c67dd464b 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_MMAN_H
-#define _ASM_X86_MMAN_H
+#ifndef ASM_X86__MMAN_H
+#define ASM_X86__MMAN_H
 
 #include <asm-generic/mman.h>
 
@@ -17,4 +17,4 @@
 #define MCL_CURRENT    1               /* lock all current mappings */
 #define MCL_FUTURE     2               /* lock all future mappings */
 
-#endif /* _ASM_X86_MMAN_H */
+#endif /* ASM_X86__MMAN_H */
index e293ab81e85017b21dbd0f534ba41692748795ec..fb79b1cf5d07bdcd24360a776a10cdca2d213274 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_MMCONFIG_H
-#define _ASM_MMCONFIG_H
+#ifndef ASM_X86__MMCONFIG_H
+#define ASM_X86__MMCONFIG_H
 
 #ifdef CONFIG_PCI_MMCONFIG
 extern void __cpuinit fam10h_check_enable_mmcfg(void);
@@ -9,4 +9,4 @@ static inline void fam10h_check_enable_mmcfg(void) { }
 static inline void check_enable_amd_mmconf_dmi(void) { }
 #endif
 
-#endif
+#endif /* ASM_X86__MMCONFIG_H */
index 00e88679e11f780af5654ae54f2bfafc7e572369..9d5aff14334a9214401d064c0bc54952e72da9c7 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_MMU_H
-#define _ASM_X86_MMU_H
+#ifndef ASM_X86__MMU_H
+#define ASM_X86__MMU_H
 
 #include <linux/spinlock.h>
 #include <linux/mutex.h>
@@ -7,14 +7,9 @@
 /*
  * The x86 doesn't have a mmu context, but
  * we put the segment information here.
- *
- * cpu_vm_mask is used to optimize ldt flushing.
  */
 typedef struct {
        void *ldt;
-#ifdef CONFIG_X86_64
-       rwlock_t ldtlock;
-#endif
        int size;
        struct mutex lock;
        void *vdso;
@@ -28,4 +23,4 @@ static inline void leave_mm(int cpu)
 }
 #endif
 
-#endif /* _ASM_X86_MMU_H */
+#endif /* ASM_X86__MMU_H */
index fac57014e7c6a4a5dbb62a7ac9e884f400c57870..8ec940bfd07902b858a9c31c00292fa429132653 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_X86_MMU_CONTEXT_H
-#define __ASM_X86_MMU_CONTEXT_H
+#ifndef ASM_X86__MMU_CONTEXT_H
+#define ASM_X86__MMU_CONTEXT_H
 
 #include <asm/desc.h>
 #include <asm/atomic.h>
@@ -34,4 +34,4 @@ do {                                          \
 } while (0);
 
 
-#endif /* __ASM_X86_MMU_CONTEXT_H */
+#endif /* ASM_X86__MMU_CONTEXT_H */
index 824fc575c6d8370f03d747b6abedaadf21882903..cce6f6e4afd6dbc6c4c876fe505da7e828647384 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __I386_SCHED_H
-#define __I386_SCHED_H
+#ifndef ASM_X86__MMU_CONTEXT_32_H
+#define ASM_X86__MMU_CONTEXT_32_H
 
 static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
 {
@@ -53,4 +53,4 @@ static inline void switch_mm(struct mm_struct *prev,
 #define deactivate_mm(tsk, mm)                 \
        asm("movl %0,%%gs": :"r" (0));
 
-#endif
+#endif /* ASM_X86__MMU_CONTEXT_32_H */
index c7000634ccae6900170be103a4b0fd99f571c55b..26758673c828b15068ea138a9527699ec7ae03d5 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __X86_64_MMU_CONTEXT_H
-#define __X86_64_MMU_CONTEXT_H
+#ifndef ASM_X86__MMU_CONTEXT_64_H
+#define ASM_X86__MMU_CONTEXT_64_H
 
 #include <asm/pda.h>
 
@@ -51,4 +51,4 @@ do {                                          \
        asm volatile("movl %0,%%fs"::"r"(0));   \
 } while (0)
 
-#endif
+#endif /* ASM_X86__MMU_CONTEXT_64_H */
index 940881218ff862ab13c349f107b2b5c6d050a5e5..2e7299bb3653639a00819fd72cea430c71d0b970 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_MMX_H
-#define _ASM_MMX_H
+#ifndef ASM_X86__MMX_H
+#define ASM_X86__MMX_H
 
 /*
  *     MMX 3Dnow! helper operations
@@ -11,4 +11,4 @@ extern void *_mmx_memcpy(void *to, const void *from, size_t size);
 extern void mmx_clear_page(void *page);
 extern void mmx_copy_page(void *to, void *from);
 
-#endif
+#endif /* ASM_X86__MMX_H */
index 5862e6460658d29fc8be6b2a9b2a26389522eb1f..121b65d61d868ca09a4a2c81d61a2c36154fbc52 100644 (file)
@@ -3,8 +3,8 @@
  *
  */
 
-#ifndef _ASM_MMZONE_H_
-#define _ASM_MMZONE_H_
+#ifndef ASM_X86__MMZONE_32_H
+#define ASM_X86__MMZONE_32_H
 
 #include <asm/smp.h>
 
@@ -131,4 +131,4 @@ static inline int pfn_valid(int pfn)
 })
 #endif /* CONFIG_NEED_MULTIPLE_NODES */
 
-#endif /* _ASM_MMZONE_H_ */
+#endif /* ASM_X86__MMZONE_32_H */
index 594bd0dc1d081db7865f80e5a33c4c8ab4f7a718..626b03a14875b20d54e2885fae78a602507f8577 100644 (file)
@@ -1,8 +1,8 @@
 /* K8 NUMA support */
 /* Copyright 2002,2003 by Andi Kleen, SuSE Labs */
 /* 2.5 Version loosely based on the NUMAQ Code by Pat Gaughen. */
-#ifndef _ASM_X86_64_MMZONE_H
-#define _ASM_X86_64_MMZONE_H 1
+#ifndef ASM_X86__MMZONE_64_H
+#define ASM_X86__MMZONE_64_H
 
 
 #ifdef CONFIG_NUMA
@@ -49,4 +49,4 @@ extern int early_pfn_to_nid(unsigned long pfn);
 #endif
 
 #endif
-#endif
+#endif /* ASM_X86__MMZONE_64_H */
index bfedb247871cfbc39ecb2823f428ac62f57eb9f4..48dc3e0c07d9a27b828ea614689a939e0baa581b 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_MODULE_H
-#define _ASM_MODULE_H
+#ifndef ASM_X86__MODULE_H
+#define ASM_X86__MODULE_H
 
 /* x86_32/64 are simple */
 struct mod_arch_specific {};
@@ -79,4 +79,4 @@ struct mod_arch_specific {};
 # define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE
 #endif
 
-#endif /* _ASM_MODULE_H */
+#endif /* ASM_X86__MODULE_H */
index b6995e567fcc64edff23e389bfad9ddeb5647508..118da365e371cf3415410fd902fd9ec85f537361 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _AM_X86_MPSPEC_H
-#define _AM_X86_MPSPEC_H
+#ifndef ASM_X86__MPSPEC_H
+#define ASM_X86__MPSPEC_H
 
 #include <linux/init.h>
 
@@ -141,4 +141,4 @@ static inline void physid_set_mask_of_physid(int physid, physid_mask_t *map)
 
 extern physid_mask_t phys_cpu_present_map;
 
-#endif
+#endif /* ASM_X86__MPSPEC_H */
index 38d1e73b49e41ebc1fdd8b07d697697b6b0fff0d..79166b04801231cf5d6526759113b071719a6226 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_MPSPEC_DEF_H
-#define __ASM_MPSPEC_DEF_H
+#ifndef ASM_X86__MPSPEC_DEF_H
+#define ASM_X86__MPSPEC_DEF_H
 
 /*
  * Structure definitions for SMP machines following the
@@ -177,4 +177,4 @@ enum mp_bustype {
        MP_BUS_PCI,
        MP_BUS_MCA,
 };
-#endif
+#endif /* ASM_X86__MPSPEC_DEF_H */
index 7e4e9481f51cff18dda6f96cfcadb5c9d9535eb9..1b538c907a3de50b0fee5d87de36238560a9fce4 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_MSGBUF_H
-#define _ASM_X86_MSGBUF_H
+#ifndef ASM_X86__MSGBUF_H
+#define ASM_X86__MSGBUF_H
 
 /*
  * The msqid64_ds structure for i386 architecture.
@@ -36,4 +36,4 @@ struct msqid64_ds {
        unsigned long  __unused5;
 };
 
-#endif /* _ASM_X86_MSGBUF_H */
+#endif /* ASM_X86__MSGBUF_H */
index 296f29ce426d4e75a3c9451d1e16bb7d8aed3f71..3139666a94fa2fab7c9bfc0f4d94713260a36a9f 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_MSIDEF_H
-#define ASM_MSIDEF_H
+#ifndef ASM_X86__MSIDEF_H
+#define ASM_X86__MSIDEF_H
 
 /*
  * Constants for Intel APIC based MSI messages.
@@ -48,4 +48,4 @@
 #define  MSI_ADDR_DEST_ID(dest)                (((dest) << MSI_ADDR_DEST_ID_SHIFT) & \
                                         MSI_ADDR_DEST_ID_MASK)
 
-#endif /* ASM_MSIDEF_H */
+#endif /* ASM_X86__MSIDEF_H */
index 44bce773012e80b11190b7400852f35a55683c98..3052f058ab063fb9cc0bf038986f4f34712320fc 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_MSR_INDEX_H
-#define __ASM_MSR_INDEX_H
+#ifndef ASM_X86__MSR_INDEX_H
+#define ASM_X86__MSR_INDEX_H
 
 /* CPU model specific register (MSR) numbers */
 
 /* Geode defined MSRs */
 #define MSR_GEODE_BUSCONT_CONF0                0x00001900
 
-#endif /* __ASM_MSR_INDEX_H */
+#endif /* ASM_X86__MSR_INDEX_H */
index 2362cfda1fbcfe08ebdc173b87b6a7818892a5f7..530af1f6389e4b1f17ed1d6002cd0b617665f50b 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_X86_MSR_H_
-#define __ASM_X86_MSR_H_
+#ifndef ASM_X86__MSR_H
+#define ASM_X86__MSR_H
 
 #include <asm/msr-index.h>
 
@@ -63,6 +63,22 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr,
        return EAX_EDX_VAL(val, low, high);
 }
 
+static inline unsigned long long native_read_msr_amd_safe(unsigned int msr,
+                                                     int *err)
+{
+       DECLARE_ARGS(val, low, high);
+
+       asm volatile("2: rdmsr ; xor %0,%0\n"
+                    "1:\n\t"
+                    ".section .fixup,\"ax\"\n\t"
+                    "3:  mov %3,%0 ; jmp 1b\n\t"
+                    ".previous\n\t"
+                    _ASM_EXTABLE(2b, 3b)
+                    : "=r" (*err), EAX_EDX_RET(val, low, high)
+                    : "c" (msr), "D" (0x9c5a203a), "i" (-EFAULT));
+       return EAX_EDX_VAL(val, low, high);
+}
+
 static inline void native_write_msr(unsigned int msr,
                                    unsigned low, unsigned high)
 {
@@ -158,6 +174,13 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p)
        *p = native_read_msr_safe(msr, &err);
        return err;
 }
+static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p)
+{
+       int err;
+
+       *p = native_read_msr_amd_safe(msr, &err);
+       return err;
+}
 
 #define rdtscl(low)                                            \
        ((low) = (u32)native_read_tsc())
@@ -221,4 +244,4 @@ static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
 #endif /* __KERNEL__ */
 
 
-#endif
+#endif /* ASM_X86__MSR_H */
index a69a01a517292ffe4d902fd157e9adb201705a11..23a7f83da953e7dee776dd7abb001a0dd5ce1374 100644 (file)
@@ -20,8 +20,8 @@
     The postal address is:
       Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
 */
-#ifndef _ASM_X86_MTRR_H
-#define _ASM_X86_MTRR_H
+#ifndef ASM_X86__MTRR_H
+#define ASM_X86__MTRR_H
 
 #include <linux/ioctl.h>
 #include <linux/errno.h>
@@ -170,4 +170,4 @@ struct mtrr_gentry32 {
 
 #endif /* __KERNEL__ */
 
-#endif  /*  _ASM_X86_MTRR_H  */
+#endif /* ASM_X86__MTRR_H */
index 73e928ef5f03b6c6160788fa9f5df2efd89c78d6..25c16d8ba3c753995394e204258583a27eebbdf4 100644 (file)
@@ -6,8 +6,8 @@
  *
  *  Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
  */
-#ifndef _ASM_MUTEX_H
-#define _ASM_MUTEX_H
+#ifndef ASM_X86__MUTEX_32_H
+#define ASM_X86__MUTEX_32_H
 
 #include <asm/alternative.h>
 
@@ -122,4 +122,4 @@ static inline int __mutex_fastpath_trylock(atomic_t *count,
 #endif
 }
 
-#endif
+#endif /* ASM_X86__MUTEX_32_H */
index f3fae9becb387c0b758ed1a639be0591bdeeb129..918ba21ab9d9c5ec2c842e0479961694f379e2cd 100644 (file)
@@ -6,8 +6,8 @@
  *
  *  Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
  */
-#ifndef _ASM_MUTEX_H
-#define _ASM_MUTEX_H
+#ifndef ASM_X86__MUTEX_64_H
+#define ASM_X86__MUTEX_64_H
 
 /**
  * __mutex_fastpath_lock - decrement and call function if negative
@@ -97,4 +97,4 @@ static inline int __mutex_fastpath_trylock(atomic_t *count,
                return 0;
 }
 
-#endif
+#endif /* ASM_X86__MUTEX_64_H */
index 21f8d0202a828ee8f6d1bf14b444e2b340f6cb3d..d5e715f024dcc79d2818d78c2f651ac8d1b32807 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_NMI_H_
-#define _ASM_X86_NMI_H_
+#ifndef ASM_X86__NMI_H
+#define ASM_X86__NMI_H
 
 #include <linux/pm.h>
 #include <asm/irq.h>
@@ -34,6 +34,7 @@ extern void stop_apic_nmi_watchdog(void *);
 extern void disable_timer_nmi_watchdog(void);
 extern void enable_timer_nmi_watchdog(void);
 extern int nmi_watchdog_tick(struct pt_regs *regs, unsigned reason);
+extern void cpu_nmi_set_wd_enabled(void);
 
 extern atomic_t nmi_active;
 extern unsigned int nmi_watchdog;
@@ -81,4 +82,4 @@ void enable_lapic_nmi_watchdog(void);
 void stop_nmi(void);
 void restart_nmi(void);
 
-#endif
+#endif /* ASM_X86__NMI_H */
index ad0bedd10b89c8e1a66c6ea6668e1d12c6a7b35b..ae742721ae73e01cdfeb9ab4e1bc72310f5ec729 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_NOPS_H
-#define _ASM_NOPS_H 1
+#ifndef ASM_X86__NOPS_H
+#define ASM_X86__NOPS_H
 
 /* Define nops for use with alternative() */
 
 
 #define ASM_NOP_MAX 8
 
-#endif
+#endif /* ASM_X86__NOPS_H */
index 220d7b7707a02be8d82232d5395732a6f9a3efa2..44cb07855c5bcfd8ab4db962c3871316f5b9027c 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_32_NUMA_H
-#define _ASM_X86_32_NUMA_H 1
+#ifndef ASM_X86__NUMA_32_H
+#define ASM_X86__NUMA_32_H
 
 extern int pxm_to_nid(int pxm);
 extern void numa_remove_cpu(int cpu);
@@ -8,4 +8,4 @@ extern void numa_remove_cpu(int cpu);
 extern void set_highmem_pages_init(void);
 #endif
 
-#endif /* _ASM_X86_32_NUMA_H */
+#endif /* ASM_X86__NUMA_32_H */
index 3830094434a9ef75eb686bb2a84ef5c10daaaef7..15c990395b021b65c766b1321ea8801e4311f9f4 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X8664_NUMA_H
-#define _ASM_X8664_NUMA_H 1
+#ifndef ASM_X86__NUMA_64_H
+#define ASM_X86__NUMA_64_H
 
 #include <linux/nodemask.h>
 #include <asm/apicdef.h>
@@ -40,4 +40,4 @@ static inline void numa_add_cpu(int cpu, int node)    { }
 static inline void numa_remove_cpu(int cpu)            { }
 #endif
 
-#endif
+#endif /* ASM_X86__NUMA_64_H */
index 34b92d581fa326839f7c2568b82d9033472d44dd..124bf7d4b70a86d483fc25409e0a6105a3acca52 100644 (file)
@@ -23,8 +23,8 @@
  * Send feedback to <gone@us.ibm.com>
  */
 
-#ifndef NUMAQ_H
-#define NUMAQ_H
+#ifndef ASM_X86__NUMAQ_H
+#define ASM_X86__NUMAQ_H
 
 #ifdef CONFIG_X86_NUMAQ
 
@@ -165,5 +165,5 @@ static inline int get_memcfg_numaq(void)
        return 0;
 }
 #endif /* CONFIG_X86_NUMAQ */
-#endif /* NUMAQ_H */
+#endif /* ASM_X86__NUMAQ_H */
 
index 97d47133486f962687683793e19673b80da7af4b..d7328b1a05c1791dc9475a573a1574c65717ccd6 100644 (file)
@@ -1,7 +1,7 @@
 /* OLPC machine specific definitions */
 
-#ifndef ASM_OLPC_H_
-#define ASM_OLPC_H_
+#ifndef ASM_X86__OLPC_H
+#define ASM_X86__OLPC_H
 
 #include <asm/geode.h>
 
@@ -129,4 +129,4 @@ extern int olpc_ec_mask_unset(uint8_t bits);
 #define OLPC_GPIO_LID          geode_gpio(26)
 #define OLPC_GPIO_ECSCI                geode_gpio(27)
 
-#endif
+#endif /* ASM_X86__OLPC_H */
index 49982110e4d94e4025896a6c05d7fddecca382ae..79544e6ffb8b8b06060ddb93988972b618e3ef02 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_PAGE_H
-#define _ASM_X86_PAGE_H
+#ifndef ASM_X86__PAGE_H
+#define ASM_X86__PAGE_H
 
 #include <linux/const.h>
 
@@ -199,4 +199,4 @@ static inline pteval_t native_pte_flags(pte_t pte)
 #define __HAVE_ARCH_GATE_AREA 1
 
 #endif /* __KERNEL__ */
-#endif /* _ASM_X86_PAGE_H */
+#endif /* ASM_X86__PAGE_H */
index ab8528793f081bef8d7c945b7bddbaf1bff54073..72f7305682c652d7ef2198b35e732d58544e808b 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_PAGE_32_H
-#define _ASM_X86_PAGE_32_H
+#ifndef ASM_X86__PAGE_32_H
+#define ASM_X86__PAGE_32_H
 
 /*
  * This handles the memory map.
@@ -89,13 +89,11 @@ extern int nx_enabled;
 extern unsigned int __VMALLOC_RESERVE;
 extern int sysctl_legacy_va_layout;
 
-#define VMALLOC_RESERVE                ((unsigned long)__VMALLOC_RESERVE)
-#define MAXMEM                 (-__PAGE_OFFSET - __VMALLOC_RESERVE)
-
 extern void find_low_pfn_range(void);
 extern unsigned long init_memory_mapping(unsigned long start,
                                         unsigned long end);
 extern void initmem_init(unsigned long, unsigned long);
+extern void free_initmem(void);
 extern void setup_bootmem_allocator(void);
 
 
@@ -126,4 +124,4 @@ static inline void copy_page(void *to, void *from)
 #endif /* CONFIG_X86_3DNOW */
 #endif /* !__ASSEMBLY__ */
 
-#endif /* _ASM_X86_PAGE_32_H */
+#endif /* ASM_X86__PAGE_32_H */
index c6916c83e6b1aee454e8a8d55ccd787652bee88e..5e64acfed0a4882b1bf392e0541b03df8d53734f 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _X86_64_PAGE_H
-#define _X86_64_PAGE_H
+#ifndef ASM_X86__PAGE_64_H
+#define ASM_X86__PAGE_64_H
 
 #define PAGETABLE_LEVELS       4
 
@@ -91,6 +91,7 @@ extern unsigned long init_memory_mapping(unsigned long start,
                                         unsigned long end);
 
 extern void initmem_init(unsigned long start_pfn, unsigned long end_pfn);
+extern void free_initmem(void);
 
 extern void init_extra_mapping_uc(unsigned long phys, unsigned long size);
 extern void init_extra_mapping_wb(unsigned long phys, unsigned long size);
@@ -102,4 +103,4 @@ extern void init_extra_mapping_wb(unsigned long phys, unsigned long size);
 #endif
 
 
-#endif /* _X86_64_PAGE_H */
+#endif /* ASM_X86__PAGE_64_H */
index 6f0d0422f4ca0ffdcb07df874789dc565f3ac82f..0009cfb11a5f53bbba0c697a6695cb6bddfefa7d 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_PARAM_H
-#define _ASM_X86_PARAM_H
+#ifndef ASM_X86__PARAM_H
+#define ASM_X86__PARAM_H
 
 #ifdef __KERNEL__
 # define HZ            CONFIG_HZ       /* Internal kernel timer frequency */
@@ -19,4 +19,4 @@
 
 #define MAXHOSTNAMELEN 64      /* max length of hostname */
 
-#endif /* _ASM_X86_PARAM_H */
+#endif /* ASM_X86__PARAM_H */
index fbbde93f12d6d5ad0aaca4fb1e6db0860cb5a351..891971f57d35d08f7f7e3b5000936a0f3babc56c 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_PARAVIRT_H
-#define __ASM_PARAVIRT_H
+#ifndef ASM_X86__PARAVIRT_H
+#define ASM_X86__PARAVIRT_H
 /* Various instructions on x86 need to be replaced for
  * para-virtualization: those hooks are defined here. */
 
@@ -137,6 +137,7 @@ struct pv_cpu_ops {
 
        /* MSR, PMC and TSR operations.
           err = 0/-EFAULT.  wrmsr returns 0/-EFAULT. */
+       u64 (*read_msr_amd)(unsigned int msr, int *err);
        u64 (*read_msr)(unsigned int msr, int *err);
        int (*write_msr)(unsigned int msr, unsigned low, unsigned high);
 
@@ -257,13 +258,13 @@ struct pv_mmu_ops {
         * Hooks for allocating/releasing pagetable pages when they're
         * attached to a pagetable
         */
-       void (*alloc_pte)(struct mm_struct *mm, u32 pfn);
-       void (*alloc_pmd)(struct mm_struct *mm, u32 pfn);
-       void (*alloc_pmd_clone)(u32 pfn, u32 clonepfn, u32 start, u32 count);
-       void (*alloc_pud)(struct mm_struct *mm, u32 pfn);
-       void (*release_pte)(u32 pfn);
-       void (*release_pmd)(u32 pfn);
-       void (*release_pud)(u32 pfn);
+       void (*alloc_pte)(struct mm_struct *mm, unsigned long pfn);
+       void (*alloc_pmd)(struct mm_struct *mm, unsigned long pfn);
+       void (*alloc_pmd_clone)(unsigned long pfn, unsigned long clonepfn, unsigned long start, unsigned long count);
+       void (*alloc_pud)(struct mm_struct *mm, unsigned long pfn);
+       void (*release_pte)(unsigned long pfn);
+       void (*release_pmd)(unsigned long pfn);
+       void (*release_pud)(unsigned long pfn);
 
        /* Pagetable manipulation functions */
        void (*set_pte)(pte_t *ptep, pte_t pteval);
@@ -726,6 +727,10 @@ static inline u64 paravirt_read_msr(unsigned msr, int *err)
 {
        return PVOP_CALL2(u64, pv_cpu_ops.read_msr, msr, err);
 }
+static inline u64 paravirt_read_msr_amd(unsigned msr, int *err)
+{
+       return PVOP_CALL2(u64, pv_cpu_ops.read_msr_amd, msr, err);
+}
 static inline int paravirt_write_msr(unsigned msr, unsigned low, unsigned high)
 {
        return PVOP_CALL3(int, pv_cpu_ops.write_msr, msr, low, high);
@@ -771,6 +776,13 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p)
        *p = paravirt_read_msr(msr, &err);
        return err;
 }
+static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p)
+{
+       int err;
+
+       *p = paravirt_read_msr_amd(msr, &err);
+       return err;
+}
 
 static inline u64 paravirt_read_tsc(void)
 {
@@ -993,35 +1005,35 @@ static inline void paravirt_pgd_free(struct mm_struct *mm, pgd_t *pgd)
        PVOP_VCALL2(pv_mmu_ops.pgd_free, mm, pgd);
 }
 
-static inline void paravirt_alloc_pte(struct mm_struct *mm, unsigned pfn)
+static inline void paravirt_alloc_pte(struct mm_struct *mm, unsigned long pfn)
 {
        PVOP_VCALL2(pv_mmu_ops.alloc_pte, mm, pfn);
 }
-static inline void paravirt_release_pte(unsigned pfn)
+static inline void paravirt_release_pte(unsigned long pfn)
 {
        PVOP_VCALL1(pv_mmu_ops.release_pte, pfn);
 }
 
-static inline void paravirt_alloc_pmd(struct mm_struct *mm, unsigned pfn)
+static inline void paravirt_alloc_pmd(struct mm_struct *mm, unsigned long pfn)
 {
        PVOP_VCALL2(pv_mmu_ops.alloc_pmd, mm, pfn);
 }
 
-static inline void paravirt_alloc_pmd_clone(unsigned pfn, unsigned clonepfn,
-                                           unsigned start, unsigned count)
+static inline void paravirt_alloc_pmd_clone(unsigned long pfn, unsigned long clonepfn,
+                                           unsigned long start, unsigned long count)
 {
        PVOP_VCALL4(pv_mmu_ops.alloc_pmd_clone, pfn, clonepfn, start, count);
 }
-static inline void paravirt_release_pmd(unsigned pfn)
+static inline void paravirt_release_pmd(unsigned long pfn)
 {
        PVOP_VCALL1(pv_mmu_ops.release_pmd, pfn);
 }
 
-static inline void paravirt_alloc_pud(struct mm_struct *mm, unsigned pfn)
+static inline void paravirt_alloc_pud(struct mm_struct *mm, unsigned long pfn)
 {
        PVOP_VCALL2(pv_mmu_ops.alloc_pud, mm, pfn);
 }
-static inline void paravirt_release_pud(unsigned pfn)
+static inline void paravirt_release_pud(unsigned long pfn)
 {
        PVOP_VCALL1(pv_mmu_ops.release_pud, pfn);
 }
@@ -1634,4 +1646,4 @@ static inline unsigned long __raw_local_irq_save(void)
 
 #endif /* __ASSEMBLY__ */
 #endif /* CONFIG_PARAVIRT */
-#endif /* __ASM_PARAVIRT_H */
+#endif /* ASM_X86__PARAVIRT_H */
index 3c4ffeb467e9886ad62b1a4c6bf60686fcb219a3..2e3dda4dc3d9b9f4bc243ca5a5b82b15be18263c 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_PARPORT_H
-#define _ASM_X86_PARPORT_H
+#ifndef ASM_X86__PARPORT_H
+#define ASM_X86__PARPORT_H
 
 static int __devinit parport_pc_find_isa_ports(int autoirq, int autodma);
 static int __devinit parport_pc_find_nonpci_ports(int autoirq, int autodma)
@@ -7,4 +7,4 @@ static int __devinit parport_pc_find_nonpci_ports(int autoirq, int autodma)
        return parport_pc_find_isa_ports(autoirq, autodma);
 }
 
-#endif /* _ASM_X86_PARPORT_H */
+#endif /* ASM_X86__PARPORT_H */
index 7edc473072179c48defd9043a2ec5be0202dbbcf..482c3e3f9879b23f086274fbd7dc453c3701ed69 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_PAT_H
-#define _ASM_PAT_H
+#ifndef ASM_X86__PAT_H
+#define ASM_X86__PAT_H
 
 #include <linux/types.h>
 
@@ -19,4 +19,4 @@ extern int free_memtype(u64 start, u64 end);
 
 extern void pat_disable(char *reason);
 
-#endif
+#endif /* ASM_X86__PAT_H */
index 80c775d9fe205810257fb8dc0013b997b5d61969..da42be07b6907bbfcf6eecabeaa65a2546cb40a1 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ASM_PCI_DIRECT_H
-#define ASM_PCI_DIRECT_H 1
+#ifndef ASM_X86__PCI_DIRECT_H
+#define ASM_X86__PCI_DIRECT_H
 
 #include <linux/types.h>
 
@@ -18,4 +18,4 @@ extern int early_pci_allowed(void);
 extern unsigned int pci_early_dump_regs;
 extern void early_dump_pci_device(u8 bus, u8 slot, u8 func);
 extern void early_dump_pci_devices(void);
-#endif
+#endif /* ASM_X86__PCI_DIRECT_H */
index 2db14cf17db8f9faeae76133445f144023d58ff6..60258319299183fa10ba7127f8af81a4e45f4f4e 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __x86_PCI_H
-#define __x86_PCI_H
+#ifndef ASM_X86__PCI_H
+#define ASM_X86__PCI_H
 
 #include <linux/mm.h> /* for struct page */
 #include <linux/types.h>
@@ -111,4 +111,4 @@ static inline cpumask_t __pcibus_to_cpumask(struct pci_bus *bus)
 }
 #endif
 
-#endif
+#endif /* ASM_X86__PCI_H */
index a50d468512857e2dd9cbdecf3b76fd986e15b1d4..3f2288207c0cd0e664cce2037d7c25e4a1bf1166 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __i386_PCI_H
-#define __i386_PCI_H
+#ifndef ASM_X86__PCI_32_H
+#define ASM_X86__PCI_32_H
 
 
 #ifdef __KERNEL__
@@ -31,4 +31,4 @@ struct pci_dev;
 #endif /* __KERNEL__ */
 
 
-#endif /* __i386_PCI_H */
+#endif /* ASM_X86__PCI_32_H */
index f330234ffa5c568888aeabf92c1e7a49d91335dc..f72e12d5770ef275aff119c8c136a70b75ed047a 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __x8664_PCI_H
-#define __x8664_PCI_H
+#ifndef ASM_X86__PCI_64_H
+#define ASM_X86__PCI_64_H
 
 #ifdef __KERNEL__
 
@@ -63,4 +63,4 @@ extern void pci_iommu_alloc(void);
 
 #endif /* __KERNEL__ */
 
-#endif /* __x8664_PCI_H */
+#endif /* ASM_X86__PCI_64_H */
index b34e9a7cc80b3002dc9e331f224298d8754482f1..80860afffbdbbede4092bb18a6946e5b0a2831f9 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef X86_64_PDA_H
-#define X86_64_PDA_H
+#ifndef ASM_X86__PDA_H
+#define ASM_X86__PDA_H
 
 #ifndef __ASSEMBLY__
 #include <linux/stddef.h>
@@ -134,4 +134,4 @@ do {                                                                        \
 
 #define PDA_STACKOFFSET (5*8)
 
-#endif
+#endif /* ASM_X86__PDA_H */
index f643a3a92da08b3789efde09f883850f0e85b0ac..e10a1d0678cfaa014ad702e1169e5d7417240f52 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_PERCPU_H_
-#define _ASM_X86_PERCPU_H_
+#ifndef ASM_X86__PERCPU_H
+#define ASM_X86__PERCPU_H
 
 #ifdef CONFIG_X86_64
 #include <linux/compiler.h>
@@ -215,4 +215,4 @@ do {                                                        \
 
 #endif /* !CONFIG_SMP */
 
-#endif /* _ASM_X86_PERCPU_H_ */
+#endif /* ASM_X86__PERCPU_H */
index d63ea431cb3bbc974bec3fa3b22e5afff0194c17..3cd23adedae851d13da954b3cb8574390102931a 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_PGALLOC_H
-#define _ASM_X86_PGALLOC_H
+#ifndef ASM_X86__PGALLOC_H
+#define ASM_X86__PGALLOC_H
 
 #include <linux/threads.h>
 #include <linux/mm.h>          /* for struct page */
@@ -111,4 +111,4 @@ extern void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pud);
 #endif /* PAGETABLE_LEVELS > 3 */
 #endif /* PAGETABLE_LEVELS > 2 */
 
-#endif /* _ASM_X86_PGALLOC_H */
+#endif /* ASM_X86__PGALLOC_H */
index 0f71c9f13da4a406e8f6e6e7d3225fe30e72c983..7ec48f4e53472a865eee5d9fb4c1b018bd3fcd8a 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _I386_PGTABLE_2LEVEL_DEFS_H
-#define _I386_PGTABLE_2LEVEL_DEFS_H
+#ifndef ASM_X86__PGTABLE_2LEVEL_DEFS_H
+#define ASM_X86__PGTABLE_2LEVEL_DEFS_H
 
 #define SHARED_KERNEL_PMD      0
 
@@ -17,4 +17,4 @@
 
 #define PTRS_PER_PTE   1024
 
-#endif /* _I386_PGTABLE_2LEVEL_DEFS_H */
+#endif /* ASM_X86__PGTABLE_2LEVEL_DEFS_H */
index 46bc52c0eae18ce519f1fe073edbed48ab846dc8..81762081dcd88251464b4af812fe39239a14377d 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _I386_PGTABLE_2LEVEL_H
-#define _I386_PGTABLE_2LEVEL_H
+#ifndef ASM_X86__PGTABLE_2LEVEL_H
+#define ASM_X86__PGTABLE_2LEVEL_H
 
 #define pte_ERROR(e) \
        printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, (e).pte_low)
@@ -53,9 +53,7 @@ static inline pte_t native_ptep_get_and_clear(pte_t *xp)
 #define native_ptep_get_and_clear(xp) native_local_ptep_get_and_clear(xp)
 #endif
 
-#define pte_page(x)            pfn_to_page(pte_pfn(x))
 #define pte_none(x)            (!(x).pte_low)
-#define pte_pfn(x)             (pte_val(x) >> PAGE_SHIFT)
 
 /*
  * Bits 0, 6 and 7 are taken, split up the 29 bits of offset
@@ -78,4 +76,4 @@ static inline pte_t native_ptep_get_and_clear(pte_t *xp)
 #define __pte_to_swp_entry(pte)                ((swp_entry_t) { (pte).pte_low })
 #define __swp_entry_to_pte(x)          ((pte_t) { .pte = (x).val })
 
-#endif /* _I386_PGTABLE_2LEVEL_H */
+#endif /* ASM_X86__PGTABLE_2LEVEL_H */
index 448ac95163145c4ded12b5d3a8db3c911d617bd3..c05fe6ff37202ddd51c596b9c27e1b609f84fb3a 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _I386_PGTABLE_3LEVEL_DEFS_H
-#define _I386_PGTABLE_3LEVEL_DEFS_H
+#ifndef ASM_X86__PGTABLE_3LEVEL_DEFS_H
+#define ASM_X86__PGTABLE_3LEVEL_DEFS_H
 
 #ifdef CONFIG_PARAVIRT
 #define SHARED_KERNEL_PMD      (pv_info.shared_kernel_pmd)
@@ -25,4 +25,4 @@
  */
 #define PTRS_PER_PTE   512
 
-#endif /* _I386_PGTABLE_3LEVEL_DEFS_H */
+#endif /* ASM_X86__PGTABLE_3LEVEL_DEFS_H */
index 105057f34032f0a23610ea5822e32cf12d51b4f7..75f4276b5ddb9e2a7fba9b3403ce9765366b0eec 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _I386_PGTABLE_3LEVEL_H
-#define _I386_PGTABLE_3LEVEL_H
+#ifndef ASM_X86__PGTABLE_3LEVEL_H
+#define ASM_X86__PGTABLE_3LEVEL_H
 
 /*
  * Intel Physical Address Extension (PAE) Mode - three-level page
@@ -151,18 +151,11 @@ static inline int pte_same(pte_t a, pte_t b)
        return a.pte_low == b.pte_low && a.pte_high == b.pte_high;
 }
 
-#define pte_page(x)    pfn_to_page(pte_pfn(x))
-
 static inline int pte_none(pte_t pte)
 {
        return !pte.pte_low && !pte.pte_high;
 }
 
-static inline unsigned long pte_pfn(pte_t pte)
-{
-       return (pte_val(pte) & PTE_PFN_MASK) >> PAGE_SHIFT;
-}
-
 /*
  * Bits 0, 6 and 7 are taken in the low part of the pte,
  * put the 32 bits of offset into the high part.
@@ -179,4 +172,4 @@ static inline unsigned long pte_pfn(pte_t pte)
 #define __pte_to_swp_entry(pte)                ((swp_entry_t){ (pte).pte_high })
 #define __swp_entry_to_pte(x)          ((pte_t){ { .pte_high = (x).val } })
 
-#endif /* _I386_PGTABLE_3LEVEL_H */
+#endif /* ASM_X86__PGTABLE_3LEVEL_H */
index 04caa2f544df4dc8c1d7798498b39d7896db1eb9..888add7b088233ab53eaf0a252f32d658de53128 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_PGTABLE_H
-#define _ASM_X86_PGTABLE_H
+#ifndef ASM_X86__PGTABLE_H
+#define ASM_X86__PGTABLE_H
 
 #define FIRST_USER_ADDRESS     0
 
@@ -186,6 +186,13 @@ static inline int pte_special(pte_t pte)
        return pte_val(pte) & _PAGE_SPECIAL;
 }
 
+static inline unsigned long pte_pfn(pte_t pte)
+{
+       return (pte_val(pte) & PTE_PFN_MASK) >> PAGE_SHIFT;
+}
+
+#define pte_page(pte)  pfn_to_page(pte_pfn(pte))
+
 static inline int pmd_large(pmd_t pte)
 {
        return (pmd_val(pte) & (_PAGE_PSE | _PAGE_PRESENT)) ==
@@ -313,6 +320,8 @@ static inline void native_pagetable_setup_start(pgd_t *base) {}
 static inline void native_pagetable_setup_done(pgd_t *base) {}
 #endif
 
+extern int arch_report_meminfo(char *page);
+
 #ifdef CONFIG_PARAVIRT
 #include <asm/paravirt.h>
 #else  /* !CONFIG_PARAVIRT */
@@ -521,4 +530,4 @@ static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
 #include <asm-generic/pgtable.h>
 #endif /* __ASSEMBLY__ */
 
-#endif /* _ASM_X86_PGTABLE_H */
+#endif /* ASM_X86__PGTABLE_H */
index 5c3b26567a95e46144cb3e2ca68601e572111e87..8de702dc7d620bc625b5ff1fe8eee2d5e0f804a9 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _I386_PGTABLE_H
-#define _I386_PGTABLE_H
+#ifndef ASM_X86__PGTABLE_32_H
+#define ASM_X86__PGTABLE_32_H
 
 
 /*
@@ -31,6 +31,7 @@ static inline void pgtable_cache_init(void) { }
 static inline void check_pgt_cache(void) { }
 void paging_init(void);
 
+extern void set_pmd_pfn(unsigned long, unsigned long, pgprot_t);
 
 /*
  * The Linux x86 paging architecture is 'compile-time dual-mode', it
@@ -56,8 +57,7 @@ void paging_init(void);
  * area for the same reason. ;)
  */
 #define VMALLOC_OFFSET (8 * 1024 * 1024)
-#define VMALLOC_START  (((unsigned long)high_memory + 2 * VMALLOC_OFFSET - 1) \
-                        & ~(VMALLOC_OFFSET - 1))
+#define VMALLOC_START  ((unsigned long)high_memory + VMALLOC_OFFSET)
 #ifdef CONFIG_X86_PAE
 #define LAST_PKMAP 512
 #else
@@ -73,6 +73,8 @@ void paging_init(void);
 # define VMALLOC_END   (FIXADDR_START - 2 * PAGE_SIZE)
 #endif
 
+#define MAXMEM (VMALLOC_END - PAGE_OFFSET - __VMALLOC_RESERVE)
+
 /*
  * Define this if things work differently on an i386 and an i486:
  * it will (on an i486) warn about kernel memory accesses that are
@@ -186,4 +188,4 @@ do {                                                \
 #define io_remap_pfn_range(vma, vaddr, pfn, size, prot)        \
        remap_pfn_range(vma, vaddr, pfn, size, prot)
 
-#endif /* _I386_PGTABLE_H */
+#endif /* ASM_X86__PGTABLE_32_H */
index 549144d03d99e7972ec2d4806b1763c2c41c933f..fde9770e53d14193a7279c8e427dc50e3f7fc87c 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _X86_64_PGTABLE_H
-#define _X86_64_PGTABLE_H
+#ifndef ASM_X86__PGTABLE_64_H
+#define ASM_X86__PGTABLE_64_H
 
 #include <linux/const.h>
 #ifndef __ASSEMBLY__
@@ -175,8 +175,6 @@ static inline int pmd_bad(pmd_t pmd)
 #define pte_present(x) (pte_val((x)) & (_PAGE_PRESENT | _PAGE_PROTNONE))
 
 #define pages_to_mb(x) ((x) >> (20 - PAGE_SHIFT))   /* FIXME: is this right? */
-#define pte_page(x)    pfn_to_page(pte_pfn((x)))
-#define pte_pfn(x)     ((pte_val((x)) & __PHYSICAL_MASK) >> PAGE_SHIFT)
 
 /*
  * Macro to mark a page protection value as "uncacheable".
@@ -284,4 +282,4 @@ extern void cleanup_highmap(void);
 #define __HAVE_ARCH_PTE_SAME
 #endif /* !__ASSEMBLY__ */
 
-#endif /* _X86_64_PGTABLE_H */
+#endif /* ASM_X86__PGTABLE_64_H */
index b031efda37ec047417dc22b6c7b61ffd7c095b19..70cf2bb059393532401e0eb4bc49528b869c5f84 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ARCH_I386_POSIX_TYPES_H
-#define __ARCH_I386_POSIX_TYPES_H
+#ifndef ASM_X86__POSIX_TYPES_32_H
+#define ASM_X86__POSIX_TYPES_32_H
 
 /*
  * This file is generally used by user-level software, so you need to
@@ -82,4 +82,4 @@ do {                                                          \
 
 #endif /* defined(__KERNEL__) */
 
-#endif
+#endif /* ASM_X86__POSIX_TYPES_32_H */
index d6624c95854af6b27db8fe2d371e3536f2862a9d..388b4e7f4a440425173adfd5f6da9bd25ead676c 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_64_POSIX_TYPES_H
-#define _ASM_X86_64_POSIX_TYPES_H
+#ifndef ASM_X86__POSIX_TYPES_64_H
+#define ASM_X86__POSIX_TYPES_64_H
 
 /*
  * This file is generally used by user-level software, so you need to
@@ -116,4 +116,4 @@ static inline void __FD_ZERO(__kernel_fd_set *p)
 
 #endif /* defined(__KERNEL__) */
 
-#endif
+#endif /* ASM_X86__POSIX_TYPES_64_H */
index 52952adef1ca8fbd4d04b14eae63f2f6315479ac..e7ae34eb4103357ac3a8b73352df7fce8caed93d 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef X86_64_PRCTL_H
-#define X86_64_PRCTL_H 1
+#ifndef ASM_X86__PRCTL_H
+#define ASM_X86__PRCTL_H
 
 #define ARCH_SET_GS 0x1001
 #define ARCH_SET_FS 0x1002
@@ -7,4 +7,4 @@
 #define ARCH_GET_GS 0x1004
 
 
-#endif
+#endif /* ASM_X86__PRCTL_H */
index eff2ecd7fff067caf89bc48cd81bebe111a43363..5dd79774f693c176d66e8e2d5ef7639d85569c25 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_I386_PROCESSOR_FLAGS_H
-#define __ASM_I386_PROCESSOR_FLAGS_H
+#ifndef ASM_X86__PROCESSOR_FLAGS_H
+#define ASM_X86__PROCESSOR_FLAGS_H
 /* Various flags defined: can be included from assembler. */
 
 /*
@@ -96,4 +96,4 @@
 #endif
 #endif
 
-#endif /* __ASM_I386_PROCESSOR_FLAGS_H */
+#endif /* ASM_X86__PROCESSOR_FLAGS_H */
index 4df3e2f6fb563f2039cbc90aa4016dce9cf9274c..5eaf9bf0a62398b84c257f627ae6a6f8273e8b7d 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_X86_PROCESSOR_H
-#define __ASM_X86_PROCESSOR_H
+#ifndef ASM_X86__PROCESSOR_H
+#define ASM_X86__PROCESSOR_H
 
 #include <asm/processor-flags.h>
 
@@ -20,6 +20,7 @@ struct mm_struct;
 #include <asm/msr.h>
 #include <asm/desc_defs.h>
 #include <asm/nops.h>
+#include <asm/ds.h>
 
 #include <linux/personality.h>
 #include <linux/cpumask.h>
@@ -140,6 +141,8 @@ DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info);
 #define current_cpu_data       boot_cpu_data
 #endif
 
+extern const struct seq_operations cpuinfo_op;
+
 static inline int hlt_works(int cpu)
 {
 #ifdef CONFIG_X86_32
@@ -153,6 +156,8 @@ static inline int hlt_works(int cpu)
 
 extern void cpu_detect(struct cpuinfo_x86 *c);
 
+extern struct pt_regs *idle_regs(struct pt_regs *);
+
 extern void early_cpu_init(void);
 extern void identify_boot_cpu(void);
 extern void identify_secondary_cpu(struct cpuinfo_x86 *);
@@ -411,9 +416,14 @@ struct thread_struct {
        unsigned                io_bitmap_max;
 /* MSR_IA32_DEBUGCTLMSR value to switch in if TIF_DEBUGCTLMSR is set.  */
        unsigned long   debugctlmsr;
-/* Debug Store - if not 0 points to a DS Save Area configuration;
- *               goes into MSR_IA32_DS_AREA */
-       unsigned long   ds_area_msr;
+#ifdef CONFIG_X86_DS
+/* Debug Store context; see include/asm-x86/ds.h; goes into MSR_IA32_DS_AREA */
+       struct ds_context       *ds_ctx;
+#endif /* CONFIG_X86_DS */
+#ifdef CONFIG_X86_PTRACE_BTS
+/* the signal to send on a bts buffer overflow */
+       unsigned int    bts_ovfl_signal;
+#endif /* CONFIG_X86_PTRACE_BTS */
 };
 
 static inline unsigned long native_get_debugreg(int regno)
@@ -943,4 +953,4 @@ extern void start_thread(struct pt_regs *regs, unsigned long new_ip,
 extern int get_tsc_mode(unsigned long adr);
 extern int set_tsc_mode(unsigned int val);
 
-#endif
+#endif /* ASM_X86__PROCESSOR_H */
index 3dd458c385c0532b59ce3aac67386ad215665dc9..6e89e8b4de0ec1c9f20f30ee2736116666a01d0e 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X8664_PROTO_H
-#define _ASM_X8664_PROTO_H 1
+#ifndef ASM_X86__PROTO_H
+#define ASM_X86__PROTO_H
 
 #include <asm/ldt.h>
 
@@ -29,4 +29,4 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr);
 #define round_up(x, y) (((x) + (y) - 1) & ~((y) - 1))
 #define round_down(x, y) ((x) & ~((y) - 1))
 
-#endif
+#endif /* ASM_X86__PROTO_H */
index 72e7b9db29bba0e2cb736d86281ab4f7c24cdd1d..4298b8882a782ab23ac101fcf48322eb78ea2cbb 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_PTRACE_ABI_H
-#define _ASM_X86_PTRACE_ABI_H
+#ifndef ASM_X86__PTRACE_ABI_H
+#define ASM_X86__PTRACE_ABI_H
 
 #ifdef __i386__
 
@@ -80,8 +80,9 @@
 
 #define PTRACE_SINGLEBLOCK     33      /* resume execution until next branch */
 
-#ifndef __ASSEMBLY__
+#ifdef CONFIG_X86_PTRACE_BTS
 
+#ifndef __ASSEMBLY__
 #include <asm/types.h>
 
 /* configuration/status structure used in PTRACE_BTS_CONFIG and
@@ -97,20 +98,20 @@ struct ptrace_bts_config {
        /* actual size of bts_struct in bytes */
        __u32 bts_size;
 };
-#endif
+#endif /* __ASSEMBLY__ */
 
 #define PTRACE_BTS_O_TRACE     0x1 /* branch trace */
 #define PTRACE_BTS_O_SCHED     0x2 /* scheduling events w/ jiffies */
 #define PTRACE_BTS_O_SIGNAL     0x4 /* send SIG<signal> on buffer overflow
                                       instead of wrapping around */
-#define PTRACE_BTS_O_CUT_SIZE  0x8 /* cut requested size to max available
-                                      instead of failing */
+#define PTRACE_BTS_O_ALLOC     0x8 /* (re)allocate buffer */
 
 #define PTRACE_BTS_CONFIG      40
 /* Configure branch trace recording.
    ADDR points to a struct ptrace_bts_config.
    DATA gives the size of that buffer.
-   A new buffer is allocated, iff the size changes.
+   A new buffer is allocated, if requested in the flags.
+   An overflow signal may only be requested for new buffers.
    Returns the number of bytes read.
 */
 #define PTRACE_BTS_STATUS      41
@@ -119,7 +120,7 @@ struct ptrace_bts_config {
    Returns the number of bytes written.
 */
 #define PTRACE_BTS_SIZE                42
-/* Return the number of available BTS records.
+/* Return the number of available BTS records for draining.
    DATA and ADDR are ignored.
 */
 #define PTRACE_BTS_GET         43
@@ -139,5 +140,6 @@ struct ptrace_bts_config {
    BTS records are read from oldest to newest.
    Returns number of BTS records drained.
 */
+#endif /* CONFIG_X86_PTRACE_BTS */
 
-#endif
+#endif /* ASM_X86__PTRACE_ABI_H */
index 8a71db803da6666bf030223503e0dcebf2778efd..d64a6109716531261d43bb1f80dc37060c6067dc 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_PTRACE_H
-#define _ASM_X86_PTRACE_H
+#ifndef ASM_X86__PTRACE_H
+#define ASM_X86__PTRACE_H
 
 #include <linux/compiler.h>    /* For __user */
 #include <asm/ptrace-abi.h>
@@ -127,14 +127,48 @@ struct pt_regs {
 #endif /* __KERNEL__ */
 #endif /* !__i386__ */
 
+
+#ifdef CONFIG_X86_PTRACE_BTS
+/* a branch trace record entry
+ *
+ * In order to unify the interface between various processor versions,
+ * we use the below data structure for all processors.
+ */
+enum bts_qualifier {
+       BTS_INVALID = 0,
+       BTS_BRANCH,
+       BTS_TASK_ARRIVES,
+       BTS_TASK_DEPARTS
+};
+
+struct bts_struct {
+       __u64 qualifier;
+       union {
+               /* BTS_BRANCH */
+               struct {
+                       __u64 from_ip;
+                       __u64 to_ip;
+               } lbr;
+               /* BTS_TASK_ARRIVES or
+                  BTS_TASK_DEPARTS */
+               __u64 jiffies;
+       } variant;
+};
+#endif /* CONFIG_X86_PTRACE_BTS */
+
 #ifdef __KERNEL__
 
-/* the DS BTS struct is used for ptrace as well */
-#include <asm/ds.h>
+#include <linux/init.h>
 
+struct cpuinfo_x86;
 struct task_struct;
 
+#ifdef CONFIG_X86_PTRACE_BTS
+extern void __cpuinit ptrace_bts_init_intel(struct cpuinfo_x86 *);
 extern void ptrace_bts_take_timestamp(struct task_struct *, enum bts_qualifier);
+#else
+#define ptrace_bts_init_intel(config) do {} while (0)
+#endif /* CONFIG_X86_PTRACE_BTS */
 
 extern unsigned long profile_pc(struct pt_regs *regs);
 
@@ -148,6 +182,9 @@ extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
 void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
 #endif
 
+extern long syscall_trace_enter(struct pt_regs *);
+extern void syscall_trace_leave(struct pt_regs *);
+
 static inline unsigned long regs_return_value(struct pt_regs *regs)
 {
        return regs->ax;
@@ -213,6 +250,11 @@ static inline unsigned long frame_pointer(struct pt_regs *regs)
        return regs->bp;
 }
 
+static inline unsigned long user_stack_pointer(struct pt_regs *regs)
+{
+       return regs->sp;
+}
+
 /*
  * These are defined as per linux/ptrace.h, which see.
  */
@@ -239,4 +281,4 @@ extern int do_set_thread_area(struct task_struct *p, int idx,
 
 #endif /* !__ASSEMBLY__ */
 
-#endif
+#endif /* ASM_X86__PTRACE_H */
index 6857f840b2436500a0483c37bb494cf2e388d939..edb3b4ecfc81687e46ff5aa8f24fb1a696349932 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_PVCLOCK_ABI_H_
-#define _ASM_X86_PVCLOCK_ABI_H_
+#ifndef ASM_X86__PVCLOCK_ABI_H
+#define ASM_X86__PVCLOCK_ABI_H
 #ifndef __ASSEMBLY__
 
 /*
@@ -39,4 +39,4 @@ struct pvclock_wall_clock {
 } __attribute__((__packed__));
 
 #endif /* __ASSEMBLY__ */
-#endif /* _ASM_X86_PVCLOCK_ABI_H_ */
+#endif /* ASM_X86__PVCLOCK_ABI_H */
index 85b1bba8e0a34a2ac4121e1fe04324f02efdb603..1a38f68348007a64dfabf488dd623bef2a463f42 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_PVCLOCK_H_
-#define _ASM_X86_PVCLOCK_H_
+#ifndef ASM_X86__PVCLOCK_H
+#define ASM_X86__PVCLOCK_H
 
 #include <linux/clocksource.h>
 #include <asm/pvclock-abi.h>
@@ -10,4 +10,4 @@ void pvclock_read_wallclock(struct pvclock_wall_clock *wall,
                            struct pvclock_vcpu_time_info *vcpu,
                            struct timespec *ts);
 
-#endif /* _ASM_X86_PVCLOCK_H_ */
+#endif /* ASM_X86__PVCLOCK_H */
index 206f355786dc5651b11777305974b281bb7a4e9f..1c2f0ce9e31e44b2c7cd8ab8a30e708f95db44c6 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_REBOOT_H
-#define _ASM_REBOOT_H
+#ifndef ASM_X86__REBOOT_H
+#define ASM_X86__REBOOT_H
 
 struct pt_regs;
 
@@ -18,4 +18,4 @@ void native_machine_crash_shutdown(struct pt_regs *regs);
 void native_machine_shutdown(void);
 void machine_real_restart(const unsigned char *code, int length);
 
-#endif /* _ASM_REBOOT_H */
+#endif /* ASM_X86__REBOOT_H */
index 0cb7d87c2b6847019032523fded1e6b4792bfdd4..2c2987d975706e891bbb5e58021b3158eacaac4a 100644 (file)
@@ -1,6 +1,6 @@
-#ifndef _LINUX_REBOOT_FIXUPS_H
-#define _LINUX_REBOOT_FIXUPS_H
+#ifndef ASM_X86__REBOOT_FIXUPS_H
+#define ASM_X86__REBOOT_FIXUPS_H
 
 extern void mach_reboot_fixups(void);
 
-#endif /* _LINUX_REBOOT_FIXUPS_H */
+#endif /* ASM_X86__REBOOT_FIXUPS_H */
index 5c2ff4bc2980b0c21d4973f52c123ab1cca45e7f..a01c4e376331ab48f65df1cd979439022fbd7cde 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_REQUIRED_FEATURES_H
-#define _ASM_REQUIRED_FEATURES_H 1
+#ifndef ASM_X86__REQUIRED_FEATURES_H
+#define ASM_X86__REQUIRED_FEATURES_H
 
 /* Define minimum CPUID feature set for kernel These bits are checked
    really early to actually display a visible error message before the
@@ -79,4 +79,4 @@
 #define REQUIRED_MASK6 0
 #define REQUIRED_MASK7 0
 
-#endif
+#endif /* ASM_X86__REQUIRED_FEATURES_H */
index 8d9f0b41ee86ca40f7f9b19d02f43c76348e1069..e39376d7de50f8e33b3bf22fb2c3d32c82bd89f9 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_RESUME_TRACE_H
-#define _ASM_X86_RESUME_TRACE_H
+#ifndef ASM_X86__RESUME_TRACE_H
+#define ASM_X86__RESUME_TRACE_H
 
 #include <asm/asm.h>
 
@@ -7,7 +7,7 @@
 do {                                                           \
        if (pm_trace_enabled) {                                 \
                const void *tracedata;                          \
-               asm volatile(_ASM_MOV_UL " $1f,%0\n"            \
+               asm volatile(_ASM_MOV " $1f,%0\n"               \
                             ".section .tracedata,\"a\"\n"      \
                             "1:\t.word %c1\n\t"                \
                             _ASM_PTR " %c2\n"                  \
@@ -18,4 +18,4 @@ do {                                                          \
        }                                                       \
 } while (0)
 
-#endif
+#endif /* ASM_X86__RESUME_TRACE_H */
index c9448bd8968f3696f800d240078e3b0510e101b7..5e1256bdee83b791499000cb873b0135437e826f 100644 (file)
@@ -5,8 +5,8 @@
  * Author: Laurent Vivier <Laurent.Vivier@bull.net>
  */
 
-#ifndef __ASM_RIO_H
-#define __ASM_RIO_H
+#ifndef ASM_X86__RIO_H
+#define ASM_X86__RIO_H
 
 #define RIO_TABLE_VERSION      3
 
@@ -60,4 +60,4 @@ enum {
        ALT_CALGARY     = 5,    /* Second Planar Calgary      */
 };
 
-#endif /* __ASM_RIO_H */
+#endif /* ASM_X86__RIO_H */
index 6a8c0d6451080658c6b2bee54fad409b11d47a9a..48a3109e1a7d83e1101c13864c444dcad3741fad 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef _ASM_X86_RWLOCK_H
-#define _ASM_X86_RWLOCK_H
+#ifndef ASM_X86__RWLOCK_H
+#define ASM_X86__RWLOCK_H
 
 #define RW_LOCK_BIAS            0x01000000
 
 /* Actual code is in asm/spinlock.h or in arch/x86/lib/rwlock.S */
 
-#endif /* _ASM_X86_RWLOCK_H */
+#endif /* ASM_X86__RWLOCK_H */
index 750f2a3542b3931044e77835dceac28457bbece8..3ff3015b71a8367f738cb8c1974c09665b569ed3 100644 (file)
@@ -29,8 +29,8 @@
  * front, then they'll all be woken up, but no other readers will be.
  */
 
-#ifndef _I386_RWSEM_H
-#define _I386_RWSEM_H
+#ifndef ASM_X86__RWSEM_H
+#define ASM_X86__RWSEM_H
 
 #ifndef _LINUX_RWSEM_H
 #error "please don't include asm/rwsem.h directly, use linux/rwsem.h instead"
@@ -262,4 +262,4 @@ static inline int rwsem_is_locked(struct rw_semaphore *sem)
 }
 
 #endif /* __KERNEL__ */
-#endif /* _I386_RWSEM_H */
+#endif /* ASM_X86__RWSEM_H */
index c0432061f81a0f0609e8b115e3c23e4ff6cdcbb4..ee48f880005d13e8244c56bf6a59cb68845fdd2e 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_SCATTERLIST_H
-#define _ASM_X86_SCATTERLIST_H
+#ifndef ASM_X86__SCATTERLIST_H
+#define ASM_X86__SCATTERLIST_H
 
 #include <asm/types.h>
 
@@ -30,4 +30,4 @@ struct scatterlist {
 # define sg_dma_len(sg)                ((sg)->dma_length)
 #endif
 
-#endif
+#endif /* ASM_X86__SCATTERLIST_H */
index 36e71c5f306f0d29d23e7856af34cf46bfc7238c..cf9ab2dbcef1f07c0e3f864579d8f75c721a6005 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_SECCOMP_H
-#define _ASM_SECCOMP_H
+#ifndef ASM_X86__SECCOMP_32_H
+#define ASM_X86__SECCOMP_32_H
 
 #include <linux/thread_info.h>
 
@@ -14,4 +14,4 @@
 #define __NR_seccomp_exit __NR_exit
 #define __NR_seccomp_sigreturn __NR_sigreturn
 
-#endif /* _ASM_SECCOMP_H */
+#endif /* ASM_X86__SECCOMP_32_H */
index 76cfe69aa63c655d969fd80994193697637326bc..03274cea751f78e460afdd6fa66bb4c1937cb3c1 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_SECCOMP_H
-#define _ASM_SECCOMP_H
+#ifndef ASM_X86__SECCOMP_64_H
+#define ASM_X86__SECCOMP_64_H
 
 #include <linux/thread_info.h>
 
@@ -22,4 +22,4 @@
 #define __NR_seccomp_exit_32 __NR_ia32_exit
 #define __NR_seccomp_sigreturn_32 __NR_ia32_sigreturn
 
-#endif /* _ASM_SECCOMP_H */
+#endif /* ASM_X86__SECCOMP_64_H */
index 646452ea9ea3ede3d7847f5be78c8ca5a0feee48..ea5f0a8686f7539e32e92f801574454c9b3a6846 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_SEGMENT_H_
-#define _ASM_X86_SEGMENT_H_
+#ifndef ASM_X86__SEGMENT_H
+#define ASM_X86__SEGMENT_H
 
 /* Constructor for a conventional segment GDT (or LDT) entry */
 /* This is a macro so it can be used in initializers */
@@ -212,4 +212,4 @@ extern const char early_idt_handlers[NUM_EXCEPTION_VECTORS][10];
 #endif
 #endif
 
-#endif
+#endif /* ASM_X86__SEGMENT_H */
index ee50c801f7b7eda1d4ea2aeea1f99cfaf1b03ccd..81f06b7e5a3f2685a88a1b7103253c3a69e34c79 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_SEMBUF_H
-#define _ASM_X86_SEMBUF_H
+#ifndef ASM_X86__SEMBUF_H
+#define ASM_X86__SEMBUF_H
 
 /*
  * The semid64_ds structure for x86 architecture.
@@ -21,4 +21,4 @@ struct semid64_ds {
        unsigned long   __unused4;
 };
 
-#endif /* _ASM_X86_SEMBUF_H */
+#endif /* ASM_X86__SEMBUF_H */
index 628c801535ea912c00a57654310a832acca2e67f..303660b671e5cf6d07d02201578225cc0dfcb3ee 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_SERIAL_H
-#define _ASM_X86_SERIAL_H
+#ifndef ASM_X86__SERIAL_H
+#define ASM_X86__SERIAL_H
 
 /*
  * This assumes you have a 1.8432 MHz clock for your UART.
@@ -26,4 +26,4 @@
        { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS },      /* ttyS2 */     \
        { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS },     /* ttyS3 */
 
-#endif /* _ASM_X86_SERIAL_H */
+#endif /* ASM_X86__SERIAL_H */
index a07c6f1c01e15b9480f14fcca8dc13d875334fc9..9030cb73c4d7acfc9def74ba772753e2710b7102 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_SETUP_H
-#define _ASM_X86_SETUP_H
+#ifndef ASM_X86__SETUP_H
+#define ASM_X86__SETUP_H
 
 #define COMMAND_LINE_SIZE 2048
 
@@ -41,6 +41,7 @@ struct x86_quirks {
 };
 
 extern struct x86_quirks *x86_quirks;
+extern unsigned long saved_video_mode;
 
 #ifndef CONFIG_PARAVIRT
 #define paravirt_post_allocator_init() do {} while (0)
@@ -100,4 +101,4 @@ void __init x86_64_start_reservations(char *real_mode_data);
 #endif /* __ASSEMBLY__ */
 #endif  /*  __KERNEL__  */
 
-#endif /* _ASM_X86_SETUP_H */
+#endif /* ASM_X86__SETUP_H */
index b51413b749711f133882d9e21c432d4c28a68463..f51aec2298e9998f919d87bc734da9d994d82860 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_SHMBUF_H
-#define _ASM_X86_SHMBUF_H
+#ifndef ASM_X86__SHMBUF_H
+#define ASM_X86__SHMBUF_H
 
 /*
  * The shmid64_ds structure for x86 architecture.
@@ -48,4 +48,4 @@ struct shminfo64 {
        unsigned long   __unused4;
 };
 
-#endif /* _ASM_X86_SHMBUF_H */
+#endif /* ASM_X86__SHMBUF_H */
index 0880cf0917b9ac3c1332d00700b96ebd3e7d012c..a83a1fd96a0e5a155b432d9fda755a7604882482 100644 (file)
@@ -1,6 +1,6 @@
-#ifndef _ASM_X86_SHMPARAM_H
-#define _ASM_X86_SHMPARAM_H
+#ifndef ASM_X86__SHMPARAM_H
+#define ASM_X86__SHMPARAM_H
 
 #define SHMLBA PAGE_SIZE        /* attach addr a multiple of this */
 
-#endif /* _ASM_X86_SHMPARAM_H */
+#endif /* ASM_X86__SHMPARAM_H */
index 2f9c884d2c0f3950f8a8179a6bd440fee0b228eb..24879c85b2914ec91821f0a67650706d45f3b3c2 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_SIGCONTEXT_H
-#define _ASM_X86_SIGCONTEXT_H
+#ifndef ASM_X86__SIGCONTEXT_H
+#define ASM_X86__SIGCONTEXT_H
 
 #include <linux/compiler.h>
 #include <asm/types.h>
@@ -202,4 +202,4 @@ struct sigcontext {
 
 #endif /* !__i386__ */
 
-#endif
+#endif /* ASM_X86__SIGCONTEXT_H */
index 57a9686fb4917a74d0ca9f6f6f18ffd3b5bdb665..4e2ec732dd0130ac278408db300a65c2b095dd94 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _SIGCONTEXT32_H
-#define _SIGCONTEXT32_H 1
+#ifndef ASM_X86__SIGCONTEXT32_H
+#define ASM_X86__SIGCONTEXT32_H
 
 /* signal context for 32bit programs. */
 
@@ -68,4 +68,4 @@ struct sigcontext_ia32 {
        unsigned int cr2;
 };
 
-#endif
+#endif /* ASM_X86__SIGCONTEXT32_H */
index a477bea0c2a12d6dd81e356470d467fb77c7ee4e..808bdfb2958c600628df8fbc52317169033e6492 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_SIGINFO_H
-#define _ASM_X86_SIGINFO_H
+#ifndef ASM_X86__SIGINFO_H
+#define ASM_X86__SIGINFO_H
 
 #ifdef __x86_64__
 # define __ARCH_SI_PREAMBLE_SIZE       (4 * sizeof(int))
@@ -7,4 +7,4 @@
 
 #include <asm-generic/siginfo.h>
 
-#endif
+#endif /* ASM_X86__SIGINFO_H */
index 6dac49364e9528c6e76d9478bf00ab9ed6b6d3bc..65acc82d267a6f3b75a42f856ae9b0ec007cf70a 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_SIGNAL_H
-#define _ASM_X86_SIGNAL_H
+#ifndef ASM_X86__SIGNAL_H
+#define ASM_X86__SIGNAL_H
 
 #ifndef __ASSEMBLY__
 #include <linux/types.h>
@@ -140,6 +140,9 @@ struct sigaction {
 struct k_sigaction {
        struct sigaction sa;
 };
+
+extern void do_notify_resume(struct pt_regs *, void *, __u32);
+
 # else /* __KERNEL__ */
 /* Here we must cater to libcs that poke about in kernel headers.  */
 
@@ -256,4 +259,4 @@ struct pt_regs;
 #endif /* __KERNEL__ */
 #endif /* __ASSEMBLY__ */
 
-#endif
+#endif /* ASM_X86__SIGNAL_H */
index 3c877f74f279454cd579cf71530ef3bd051b75ff..04f84f4e2c8b727d82835574c6c2d0117bbef25e 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_SMP_H_
-#define _ASM_X86_SMP_H_
+#ifndef ASM_X86__SMP_H
+#define ASM_X86__SMP_H
 #ifndef __ASSEMBLY__
 #include <linux/cpumask.h>
 #include <linux/init.h>
@@ -34,6 +34,9 @@ extern cpumask_t cpu_initialized;
 DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
 DECLARE_PER_CPU(cpumask_t, cpu_core_map);
 DECLARE_PER_CPU(u16, cpu_llc_id);
+#ifdef CONFIG_X86_32
+DECLARE_PER_CPU(int, cpu_number);
+#endif
 
 DECLARE_EARLY_PER_CPU(u16, x86_cpu_to_apicid);
 DECLARE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid);
@@ -142,7 +145,6 @@ extern unsigned disabled_cpus __cpuinitdata;
  * from the initial startup. We map APIC_BASE very early in page_setup(),
  * so this is correct in the x86 case.
  */
-DECLARE_PER_CPU(int, cpu_number);
 #define raw_smp_processor_id() (x86_read_percpu(cpu_number))
 extern int safe_smp_processor_id(void);
 
@@ -205,4 +207,4 @@ extern void cpu_uninit(void);
 #endif
 
 #endif /* __ASSEMBLY__ */
-#endif
+#endif /* ASM_X86__SMP_H */
index 80af9c4ccad7f05cd09db4d0d212ec2a0753ed04..db73274c83c3b3ea302dff7a233fab452745c838 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_SOCKET_H
-#define _ASM_SOCKET_H
+#ifndef ASM_X86__SOCKET_H
+#define ASM_X86__SOCKET_H
 
 #include <asm/sockios.h>
 
@@ -54,4 +54,4 @@
 
 #define SO_MARK                        36
 
-#endif /* _ASM_SOCKET_H */
+#endif /* ASM_X86__SOCKET_H */
index 49cc72b5d3c914fa5bb98f181e37768018cc6782..a006704fdc8427cf4b4cd134bf9695375dbc3af5 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_SOCKIOS_H
-#define _ASM_X86_SOCKIOS_H
+#ifndef ASM_X86__SOCKIOS_H
+#define ASM_X86__SOCKIOS_H
 
 /* Socket-level I/O control calls. */
 #define FIOSETOWN      0x8901
@@ -10,4 +10,4 @@
 #define SIOCGSTAMP     0x8906          /* Get stamp (timeval) */
 #define SIOCGSTAMPNS   0x8907          /* Get stamp (timespec) */
 
-#endif /* _ASM_X86_SOCKIOS_H */
+#endif /* ASM_X86__SOCKIOS_H */
index 9bd48b0a534ba7b76ffeb439e9276af540a35081..38f8e6bc3186bb52ce64245870d651f20c24d6fd 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_SPARSEMEM_H
-#define _ASM_X86_SPARSEMEM_H
+#ifndef ASM_X86__SPARSEMEM_H
+#define ASM_X86__SPARSEMEM_H
 
 #ifdef CONFIG_SPARSEMEM
 /*
@@ -31,4 +31,4 @@
 #endif
 
 #endif /* CONFIG_SPARSEMEM */
-#endif
+#endif /* ASM_X86__SPARSEMEM_H */
index e39c790dbfd2be789d812a6cdd89efc3d39cb5ec..93adae338ac64625ab1c1ec63634edd8c3d8dcd3 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _X86_SPINLOCK_H_
-#define _X86_SPINLOCK_H_
+#ifndef ASM_X86__SPINLOCK_H
+#define ASM_X86__SPINLOCK_H
 
 #include <asm/atomic.h>
 #include <asm/rwlock.h>
@@ -97,7 +97,7 @@ static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock)
                     "jne 1f\n\t"
                     "movw %w0,%w1\n\t"
                     "incb %h1\n\t"
-                    "lock ; cmpxchgw %w1,%2\n\t"
+                    LOCK_PREFIX "cmpxchgw %w1,%2\n\t"
                     "1:"
                     "sete %b1\n\t"
                     "movzbl %b1,%0\n\t"
@@ -135,7 +135,7 @@ static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock)
        int inc = 0x00010000;
        int tmp;
 
-       asm volatile("lock ; xaddl %0, %1\n"
+       asm volatile(LOCK_PREFIX "xaddl %0, %1\n"
                     "movzwl %w0, %2\n\t"
                     "shrl $16, %0\n\t"
                     "1:\t"
@@ -162,7 +162,7 @@ static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock)
                     "cmpl %0,%1\n\t"
                     "jne 1f\n\t"
                     "addl $0x00010000, %1\n\t"
-                    "lock ; cmpxchgl %1,%2\n\t"
+                    LOCK_PREFIX "cmpxchgl %1,%2\n\t"
                     "1:"
                     "sete %b1\n\t"
                     "movzbl %b1,%0\n\t"
@@ -366,4 +366,4 @@ static inline void __raw_write_unlock(raw_rwlock_t *rw)
 #define _raw_read_relax(lock)  cpu_relax()
 #define _raw_write_relax(lock) cpu_relax()
 
-#endif
+#endif /* ASM_X86__SPINLOCK_H */
index 06c071c9eee9f1d2e5288930b91e511a3d094d61..6aa9b562c5080ae0ac7295a0adefea9ff31c138b 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_SPINLOCK_TYPES_H
-#define __ASM_SPINLOCK_TYPES_H
+#ifndef ASM_X86__SPINLOCK_TYPES_H
+#define ASM_X86__SPINLOCK_TYPES_H
 
 #ifndef __LINUX_SPINLOCK_TYPES_H
 # error "please don't include this file directly"
@@ -17,4 +17,4 @@ typedef struct {
 
 #define __RAW_RW_LOCK_UNLOCKED         { RW_LOCK_BIAS }
 
-#endif
+#endif /* ASM_X86__SPINLOCK_TYPES_H */
index 774c919dc2323cb7ecb85b1350876146414286db..5363e4f7e1cddb7b52f0db52be72eb185f5a2a5a 100644 (file)
@@ -24,8 +24,8 @@
  * Send feedback to Pat Gaughen <gone@us.ibm.com>
  */
 
-#ifndef _ASM_SRAT_H_
-#define _ASM_SRAT_H_
+#ifndef ASM_X86__SRAT_H
+#define ASM_X86__SRAT_H
 
 #ifdef CONFIG_ACPI_NUMA
 extern int get_memcfg_from_srat(void);
@@ -36,4 +36,4 @@ static inline int get_memcfg_from_srat(void)
 }
 #endif
 
-#endif /* _ASM_SRAT_H_ */
+#endif /* ASM_X86__SRAT_H */
index 30f82526a8e285547ea890febb757890d3ad4cde..f43517e28532fd930a6cf017591ac7f1bee5febc 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_STACKTRACE_H
-#define _ASM_STACKTRACE_H 1
+#ifndef ASM_X86__STACKTRACE_H
+#define ASM_X86__STACKTRACE_H
 
 extern int kstack_depth_to_print;
 
@@ -18,4 +18,4 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
                unsigned long *stack, unsigned long bp,
                const struct stacktrace_ops *ops, void *data);
 
-#endif
+#endif /* ASM_X86__STACKTRACE_H */
index 5c22dcb5d17e2e49fcae06e6b86db425730dcbad..1e120f62890546f58311c213d8f46d8ec2f0d065 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_STAT_H
-#define _ASM_X86_STAT_H
+#ifndef ASM_X86__STAT_H
+#define ASM_X86__STAT_H
 
 #define STAT_HAVE_NSEC 1
 
@@ -111,4 +111,4 @@ struct __old_kernel_stat {
 #endif
 };
 
-#endif
+#endif /* ASM_X86__STAT_H */
index 7c651aa972527928788a63648b567bf8bd70aec7..3f005bc3aa5bb0e35c6421927f6ad999d8181a1f 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_STATFS_H
-#define _ASM_X86_STATFS_H
+#ifndef ASM_X86__STATFS_H
+#define ASM_X86__STATFS_H
 
 #ifdef __i386__
 #include <asm-generic/statfs.h>
@@ -60,4 +60,4 @@ struct compat_statfs64 {
 } __attribute__((packed));
 
 #endif /* !__i386__ */
-#endif
+#endif /* ASM_X86__STATFS_H */
index 193578cd1fd98af422fb5146c110ca03625d26cb..487843ed245a54bd91dadaca58413b650b0976cb 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _I386_STRING_H_
-#define _I386_STRING_H_
+#ifndef ASM_X86__STRING_32_H
+#define ASM_X86__STRING_32_H
 
 #ifdef __KERNEL__
 
@@ -323,4 +323,4 @@ extern void *memscan(void *addr, int c, size_t size);
 
 #endif /* __KERNEL__ */
 
-#endif
+#endif /* ASM_X86__STRING_32_H */
index 52b5ab383395fde07df5e4d71f8899c8982d26b2..a2add11d3b66a6424f528cd365aaf6818db9556a 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _X86_64_STRING_H_
-#define _X86_64_STRING_H_
+#ifndef ASM_X86__STRING_64_H
+#define ASM_X86__STRING_64_H
 
 #ifdef __KERNEL__
 
@@ -57,4 +57,4 @@ int strcmp(const char *cs, const char *ct);
 
 #endif /* __KERNEL__ */
 
-#endif
+#endif /* ASM_X86__STRING_64_H */
index 8675c6782a7da2754a4b391bab931b920db9a009..acb6d4d491f4d35b704b2dac6e52ce21cb409161 100644 (file)
@@ -3,8 +3,8 @@
  * Based on code
  * Copyright 2001 Patrick Mochel <mochel@osdl.org>
  */
-#ifndef __ASM_X86_32_SUSPEND_H
-#define __ASM_X86_32_SUSPEND_H
+#ifndef ASM_X86__SUSPEND_32_H
+#define ASM_X86__SUSPEND_32_H
 
 #include <asm/desc.h>
 #include <asm/i387.h>
@@ -48,4 +48,4 @@ static inline void acpi_save_register_state(unsigned long return_point)
 extern int acpi_save_state_mem(void);
 #endif
 
-#endif /* __ASM_X86_32_SUSPEND_H */
+#endif /* ASM_X86__SUSPEND_32_H */
index dc3262b4307291bffd206e4c015d9743ae8d0a33..cf821dd310e81c9bf8858452188f70152bfe17a3 100644 (file)
@@ -3,8 +3,8 @@
  * Based on code
  * Copyright 2001 Patrick Mochel <mochel@osdl.org>
  */
-#ifndef __ASM_X86_64_SUSPEND_H
-#define __ASM_X86_64_SUSPEND_H
+#ifndef ASM_X86__SUSPEND_64_H
+#define ASM_X86__SUSPEND_64_H
 
 #include <asm/desc.h>
 #include <asm/i387.h>
@@ -49,4 +49,4 @@ extern int acpi_save_state_mem(void);
 extern char core_restore_code;
 extern char restore_registers;
 
-#endif /* __ASM_X86_64_SUSPEND_H */
+#endif /* ASM_X86__SUSPEND_64_H */
index 2730b351afcf2422695ca176cf8a7edbee57b9cc..1e20adbcad4b0cff70243b4ed71c7182e2371c64 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_SWIOTLB_H
-#define _ASM_SWIOTLB_H 1
+#ifndef ASM_X86__SWIOTLB_H
+#define ASM_X86__SWIOTLB_H
 
 #include <asm/dma-mapping.h>
 
@@ -55,4 +55,4 @@ static inline void pci_swiotlb_init(void)
 
 static inline void dma_mark_clean(void *addr, size_t size) {}
 
-#endif /* _ASM_SWIOTLB_H */
+#endif /* ASM_X86__SWIOTLB_H */
index b47a1d0b8a834719866a713dadf65a28fd566a4c..b689bee71104da4ba5b9eff3fa597606cfdd9de3 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _I386_SYNC_BITOPS_H
-#define _I386_SYNC_BITOPS_H
+#ifndef ASM_X86__SYNC_BITOPS_H
+#define ASM_X86__SYNC_BITOPS_H
 
 /*
  * Copyright 1992, Linus Torvalds.
@@ -127,4 +127,4 @@ static inline int sync_test_and_change_bit(int nr, volatile unsigned long *addr)
 
 #undef ADDR
 
-#endif /* _I386_SYNC_BITOPS_H */
+#endif /* ASM_X86__SYNC_BITOPS_H */
diff --git a/include/asm-x86/syscall.h b/include/asm-x86/syscall.h
new file mode 100644 (file)
index 0000000..04c47dc
--- /dev/null
@@ -0,0 +1,211 @@
+/*
+ * Access to user system call parameters and results
+ *
+ * Copyright (C) 2008 Red Hat, Inc.  All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * See asm-generic/syscall.h for descriptions of what we must do here.
+ */
+
+#ifndef _ASM_SYSCALL_H
+#define _ASM_SYSCALL_H 1
+
+#include <linux/sched.h>
+#include <linux/err.h>
+
+static inline long syscall_get_nr(struct task_struct *task,
+                                 struct pt_regs *regs)
+{
+       /*
+        * We always sign-extend a -1 value being set here,
+        * so this is always either -1L or a syscall number.
+        */
+       return regs->orig_ax;
+}
+
+static inline void syscall_rollback(struct task_struct *task,
+                                   struct pt_regs *regs)
+{
+       regs->ax = regs->orig_ax;
+}
+
+static inline long syscall_get_error(struct task_struct *task,
+                                    struct pt_regs *regs)
+{
+       unsigned long error = regs->ax;
+#ifdef CONFIG_IA32_EMULATION
+       /*
+        * TS_COMPAT is set for 32-bit syscall entries and then
+        * remains set until we return to user mode.
+        */
+       if (task_thread_info(task)->status & TS_COMPAT)
+               /*
+                * Sign-extend the value so (int)-EFOO becomes (long)-EFOO
+                * and will match correctly in comparisons.
+                */
+               error = (long) (int) error;
+#endif
+       return IS_ERR_VALUE(error) ? error : 0;
+}
+
+static inline long syscall_get_return_value(struct task_struct *task,
+                                           struct pt_regs *regs)
+{
+       return regs->ax;
+}
+
+static inline void syscall_set_return_value(struct task_struct *task,
+                                           struct pt_regs *regs,
+                                           int error, long val)
+{
+       regs->ax = (long) error ?: val;
+}
+
+#ifdef CONFIG_X86_32
+
+static inline void syscall_get_arguments(struct task_struct *task,
+                                        struct pt_regs *regs,
+                                        unsigned int i, unsigned int n,
+                                        unsigned long *args)
+{
+       BUG_ON(i + n > 6);
+       memcpy(args, &regs->bx + i, n * sizeof(args[0]));
+}
+
+static inline void syscall_set_arguments(struct task_struct *task,
+                                        struct pt_regs *regs,
+                                        unsigned int i, unsigned int n,
+                                        const unsigned long *args)
+{
+       BUG_ON(i + n > 6);
+       memcpy(&regs->bx + i, args, n * sizeof(args[0]));
+}
+
+#else   /* CONFIG_X86_64 */
+
+static inline void syscall_get_arguments(struct task_struct *task,
+                                        struct pt_regs *regs,
+                                        unsigned int i, unsigned int n,
+                                        unsigned long *args)
+{
+# ifdef CONFIG_IA32_EMULATION
+       if (task_thread_info(task)->status & TS_COMPAT)
+               switch (i + n) {
+               case 6:
+                       if (!n--) break;
+                       *args++ = regs->bp;
+               case 5:
+                       if (!n--) break;
+                       *args++ = regs->di;
+               case 4:
+                       if (!n--) break;
+                       *args++ = regs->si;
+               case 3:
+                       if (!n--) break;
+                       *args++ = regs->dx;
+               case 2:
+                       if (!n--) break;
+                       *args++ = regs->cx;
+               case 1:
+                       if (!n--) break;
+                       *args++ = regs->bx;
+               case 0:
+                       if (!n--) break;
+               default:
+                       BUG();
+                       break;
+               }
+       else
+# endif
+               switch (i + n) {
+               case 6:
+                       if (!n--) break;
+                       *args++ = regs->r9;
+               case 5:
+                       if (!n--) break;
+                       *args++ = regs->r8;
+               case 4:
+                       if (!n--) break;
+                       *args++ = regs->r10;
+               case 3:
+                       if (!n--) break;
+                       *args++ = regs->dx;
+               case 2:
+                       if (!n--) break;
+                       *args++ = regs->si;
+               case 1:
+                       if (!n--) break;
+                       *args++ = regs->di;
+               case 0:
+                       if (!n--) break;
+               default:
+                       BUG();
+                       break;
+               }
+}
+
+static inline void syscall_set_arguments(struct task_struct *task,
+                                        struct pt_regs *regs,
+                                        unsigned int i, unsigned int n,
+                                        const unsigned long *args)
+{
+# ifdef CONFIG_IA32_EMULATION
+       if (task_thread_info(task)->status & TS_COMPAT)
+               switch (i + n) {
+               case 6:
+                       if (!n--) break;
+                       regs->bp = *args++;
+               case 5:
+                       if (!n--) break;
+                       regs->di = *args++;
+               case 4:
+                       if (!n--) break;
+                       regs->si = *args++;
+               case 3:
+                       if (!n--) break;
+                       regs->dx = *args++;
+               case 2:
+                       if (!n--) break;
+                       regs->cx = *args++;
+               case 1:
+                       if (!n--) break;
+                       regs->bx = *args++;
+               case 0:
+                       if (!n--) break;
+               default:
+                       BUG();
+               }
+       else
+# endif
+               switch (i + n) {
+               case 6:
+                       if (!n--) break;
+                       regs->r9 = *args++;
+               case 5:
+                       if (!n--) break;
+                       regs->r8 = *args++;
+               case 4:
+                       if (!n--) break;
+                       regs->r10 = *args++;
+               case 3:
+                       if (!n--) break;
+                       regs->dx = *args++;
+               case 2:
+                       if (!n--) break;
+                       regs->si = *args++;
+               case 1:
+                       if (!n--) break;
+                       regs->di = *args++;
+               case 0:
+                       if (!n--) break;
+               default:
+                       BUG();
+               }
+}
+
+#endif /* CONFIG_X86_32 */
+
+#endif /* _ASM_SYSCALL_H */
diff --git a/include/asm-x86/syscalls.h b/include/asm-x86/syscalls.h
new file mode 100644 (file)
index 0000000..87803da
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * syscalls.h - Linux syscall interfaces (arch-specific)
+ *
+ * Copyright (c) 2008 Jaswinder Singh
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
+#ifndef _ASM_X86_SYSCALLS_H
+#define _ASM_X86_SYSCALLS_H
+
+#include <linux/compiler.h>
+#include <linux/linkage.h>
+#include <linux/types.h>
+#include <linux/signal.h>
+
+/* Common in X86_32 and X86_64 */
+/* kernel/ioport.c */
+asmlinkage long sys_ioperm(unsigned long, unsigned long, int);
+
+/* X86_32 only */
+#ifdef CONFIG_X86_32
+/* kernel/process_32.c */
+asmlinkage int sys_fork(struct pt_regs);
+asmlinkage int sys_clone(struct pt_regs);
+asmlinkage int sys_vfork(struct pt_regs);
+asmlinkage int sys_execve(struct pt_regs);
+
+/* kernel/signal_32.c */
+asmlinkage int sys_sigsuspend(int, int, old_sigset_t);
+asmlinkage int sys_sigaction(int, const struct old_sigaction __user *,
+                            struct old_sigaction __user *);
+asmlinkage int sys_sigaltstack(unsigned long);
+asmlinkage unsigned long sys_sigreturn(unsigned long);
+asmlinkage int sys_rt_sigreturn(unsigned long);
+
+/* kernel/ioport.c */
+asmlinkage long sys_iopl(unsigned long);
+
+/* kernel/ldt.c */
+asmlinkage int sys_modify_ldt(int, void __user *, unsigned long);
+
+/* kernel/sys_i386_32.c */
+asmlinkage long sys_mmap2(unsigned long, unsigned long, unsigned long,
+                         unsigned long, unsigned long, unsigned long);
+struct mmap_arg_struct;
+asmlinkage int old_mmap(struct mmap_arg_struct __user *);
+struct sel_arg_struct;
+asmlinkage int old_select(struct sel_arg_struct __user *);
+asmlinkage int sys_ipc(uint, int, int, int, void __user *, long);
+struct old_utsname;
+asmlinkage int sys_uname(struct old_utsname __user *);
+struct oldold_utsname;
+asmlinkage int sys_olduname(struct oldold_utsname __user *);
+
+/* kernel/tls.c */
+asmlinkage int sys_set_thread_area(struct user_desc __user *);
+asmlinkage int sys_get_thread_area(struct user_desc __user *);
+
+/* kernel/vm86_32.c */
+asmlinkage int sys_vm86old(struct pt_regs);
+asmlinkage int sys_vm86(struct pt_regs);
+
+#else /* CONFIG_X86_32 */
+
+/* X86_64 only */
+/* kernel/process_64.c */
+asmlinkage long sys_fork(struct pt_regs *);
+asmlinkage long sys_clone(unsigned long, unsigned long,
+                         void __user *, void __user *,
+                         struct pt_regs *);
+asmlinkage long sys_vfork(struct pt_regs *);
+asmlinkage long sys_execve(char __user *, char __user * __user *,
+                          char __user * __user *,
+                          struct pt_regs *);
+
+/* kernel/ioport.c */
+asmlinkage long sys_iopl(unsigned int, struct pt_regs *);
+
+/* kernel/signal_64.c */
+asmlinkage long sys_sigaltstack(const stack_t __user *, stack_t __user *,
+                               struct pt_regs *);
+asmlinkage long sys_rt_sigreturn(struct pt_regs *);
+
+/* kernel/sys_x86_64.c */
+asmlinkage long sys_mmap(unsigned long, unsigned long, unsigned long,
+                        unsigned long, unsigned long, unsigned long);
+struct new_utsname;
+asmlinkage long sys_uname(struct new_utsname __user *);
+
+#endif /* CONFIG_X86_32 */
+#endif /* _ASM_X86_SYSCALLS_H */
index 983ce37c491fd83504fd0a82ff3a7da15f608861..34505dd7b24de4ad67b968f93b3fc24156700206 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_SYSTEM_H_
-#define _ASM_X86_SYSTEM_H_
+#ifndef ASM_X86__SYSTEM_H
+#define ASM_X86__SYSTEM_H
 
 #include <asm/asm.h>
 #include <asm/segment.h>
@@ -419,4 +419,4 @@ static inline void rdtsc_barrier(void)
        alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC);
 }
 
-#endif
+#endif /* ASM_X86__SYSTEM_H */
index 97fa251ccb2b088d055e0332fb97d50e5aeb480d..5aedb8bffc5a0c50fc3e6ac4576efc4686a94b37 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_SYSTEM_H
-#define __ASM_SYSTEM_H
+#ifndef ASM_X86__SYSTEM_64_H
+#define ASM_X86__SYSTEM_64_H
 
 #include <asm/segment.h>
 #include <asm/cmpxchg.h>
@@ -19,4 +19,4 @@ static inline void write_cr8(unsigned long val)
 
 #include <linux/irqflags.h>
 
-#endif
+#endif /* ASM_X86__SYSTEM_64_H */
index b1a4ea00df783cb86ea52818fb148c4d86a31ae3..e7932d7fbbab9d10ccff23b170f54d20a9e15a32 100644 (file)
@@ -21,8 +21,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
-#ifndef _ASM_X86_64_TCE_H
-#define _ASM_X86_64_TCE_H
+#ifndef ASM_X86__TCE_H
+#define ASM_X86__TCE_H
 
 extern unsigned int specified_table_size;
 struct iommu_table;
@@ -45,4 +45,4 @@ extern void * __init alloc_tce_table(void);
 extern void __init free_tce_table(void *tbl);
 extern int __init build_tce_table(struct pci_dev *dev, void __iomem *bbar);
 
-#endif /* _ASM_X86_64_TCE_H */
+#endif /* ASM_X86__TCE_H */
index af1b70ea440fe2e4d6fded733d86a91bcb4d89af..3d00dc5e0c717967fb0b5a73663df7850c695a58 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_TERMBITS_H
-#define _ASM_X86_TERMBITS_H
+#ifndef ASM_X86__TERMBITS_H
+#define ASM_X86__TERMBITS_H
 
 #include <linux/posix_types.h>
 
@@ -195,4 +195,4 @@ struct ktermios {
 #define        TCSADRAIN       1
 #define        TCSAFLUSH       2
 
-#endif /* _ASM_X86_TERMBITS_H */
+#endif /* ASM_X86__TERMBITS_H */
index f72956331c49349623014bffc4c241f01c361eee..e235db248071f4cbc14a881049e215b2ab6bd038 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_TERMIOS_H
-#define _ASM_X86_TERMIOS_H
+#ifndef ASM_X86__TERMIOS_H
+#define ASM_X86__TERMIOS_H
 
 #include <asm/termbits.h>
 #include <asm/ioctls.h>
@@ -110,4 +110,4 @@ static inline int kernel_termios_to_user_termios_1(struct termios __user *u,
 
 #endif /* __KERNEL__ */
 
-#endif /* _ASM_X86_TERMIOS_H */
+#endif /* ASM_X86__TERMIOS_H */
index 399bf6026b16c8fd8f17a9fcf154653321495c7a..1c7f57b6b66e413ae52bda3d2c4162703870aed0 100644 (file)
@@ -1,9 +1,9 @@
-#ifndef __ASM_I386_THERM_THROT_H__
-#define __ASM_I386_THERM_THROT_H__ 1
+#ifndef ASM_X86__THERM_THROT_H
+#define ASM_X86__THERM_THROT_H
 
 #include <asm/atomic.h>
 
 extern atomic_t therm_throt_en;
 int therm_throt_process(int curr);
 
-#endif /* __ASM_I386_THERM_THROT_H__ */
+#endif /* ASM_X86__THERM_THROT_H */
index da0a675adf94a1a753792d1bca54c45d4fe3bed4..4db0066a3a3597fab71fc9079bb5b55180ab1070 100644 (file)
@@ -4,8 +4,8 @@
  * - Incorporating suggestions made by Linus Torvalds and Dave Miller
  */
 
-#ifndef _ASM_X86_THREAD_INFO_H
-#define _ASM_X86_THREAD_INFO_H
+#ifndef ASM_X86__THREAD_INFO_H
+#define ASM_X86__THREAD_INFO_H
 
 #include <linux/compiler.h>
 #include <asm/page.h>
@@ -71,6 +71,7 @@ struct thread_info {
  * Warning: layout of LSW is hardcoded in entry.S
  */
 #define TIF_SYSCALL_TRACE      0       /* syscall trace active */
+#define TIF_NOTIFY_RESUME      1       /* callback before returning to user */
 #define TIF_SIGPENDING         2       /* signal pending */
 #define TIF_NEED_RESCHED       3       /* rescheduling necessary */
 #define TIF_SINGLESTEP         4       /* reenable singlestep on user return*/
@@ -93,6 +94,7 @@ struct thread_info {
 #define TIF_BTS_TRACE_TS       27      /* record scheduling event timestamps */
 
 #define _TIF_SYSCALL_TRACE     (1 << TIF_SYSCALL_TRACE)
+#define _TIF_NOTIFY_RESUME     (1 << TIF_NOTIFY_RESUME)
 #define _TIF_SIGPENDING                (1 << TIF_SIGPENDING)
 #define _TIF_SINGLESTEP                (1 << TIF_SINGLESTEP)
 #define _TIF_NEED_RESCHED      (1 << TIF_NEED_RESCHED)
@@ -133,7 +135,7 @@ struct thread_info {
 
 /* Only used for 64 bit */
 #define _TIF_DO_NOTIFY_MASK                                            \
-       (_TIF_SIGPENDING|_TIF_MCE_NOTIFY)
+       (_TIF_SIGPENDING|_TIF_MCE_NOTIFY|_TIF_NOTIFY_RESUME)
 
 /* flags to check in __switch_to() */
 #define _TIF_WORK_CTXSW                                                        \
@@ -258,4 +260,4 @@ extern void free_thread_info(struct thread_info *ti);
 extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
 #define arch_task_cache_init arch_task_cache_init
 #endif
-#endif /* _ASM_X86_THREAD_INFO_H */
+#endif /* ASM_X86__THREAD_INFO_H */
index a17fa473e91d41b496972aef624d3ab6483f9f91..3e724eef7ac468f118bb8c7c95edac31577cc739 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASMX86_TIME_H
-#define _ASMX86_TIME_H
+#ifndef ASM_X86__TIME_H
+#define ASM_X86__TIME_H
 
 extern void hpet_time_init(void);
 
@@ -46,6 +46,8 @@ static inline int native_set_wallclock(unsigned long nowtime)
 
 #endif
 
+extern void time_init(void);
+
 #ifdef CONFIG_PARAVIRT
 #include <asm/paravirt.h>
 #else /* !CONFIG_PARAVIRT */
@@ -58,4 +60,4 @@ static inline int native_set_wallclock(unsigned long nowtime)
 
 extern unsigned long __init calibrate_cpu(void);
 
-#endif
+#endif /* ASM_X86__TIME_H */
index fb2a4ddddf3d083296d0248c759071f3cc450b3e..d0babce4b47a6ecbc9d3ca62bf084665c49a02b9 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASMi386_TIMER_H
-#define _ASMi386_TIMER_H
+#ifndef ASM_X86__TIMER_H
+#define ASM_X86__TIMER_H
 #include <linux/init.h>
 #include <linux/pm.h>
 #include <linux/percpu.h>
@@ -9,9 +9,12 @@
 unsigned long long native_sched_clock(void);
 unsigned long native_calibrate_tsc(void);
 
+#ifdef CONFIG_X86_32
 extern int timer_ack;
-extern int no_timer_check;
 extern int recalibrate_cpu_khz(void);
+#endif /* CONFIG_X86_32 */
+
+extern int no_timer_check;
 
 #ifndef CONFIG_PARAVIRT
 #define calibrate_tsc() native_calibrate_tsc()
@@ -60,4 +63,4 @@ static inline unsigned long long cycles_2_ns(unsigned long long cyc)
        return ns;
 }
 
-#endif
+#endif /* ASM_X86__TIMER_H */
index 43e5a78500c57905fa8c24f5397f37a86a13fd7a..d1ce2416a5da14e61d151150622e4dbe7491c866 100644 (file)
@@ -1,6 +1,6 @@
 /* x86 architecture timex specifications */
-#ifndef _ASM_X86_TIMEX_H
-#define _ASM_X86_TIMEX_H
+#ifndef ASM_X86__TIMEX_H
+#define ASM_X86__TIMEX_H
 
 #include <asm/processor.h>
 #include <asm/tsc.h>
@@ -16,4 +16,4 @@
 
 #define ARCH_HAS_READ_CURRENT_TIMER
 
-#endif
+#endif /* ASM_X86__TIMEX_H */
index e4e9e2d07a93194b0ec45a5c4863464bfe1b333c..db36e9e89e873c7d65a2115c119ec7d828aa6133 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_TLB_H
-#define _ASM_X86_TLB_H
+#ifndef ASM_X86__TLB_H
+#define ASM_X86__TLB_H
 
 #define tlb_start_vma(tlb, vma) do { } while (0)
 #define tlb_end_vma(tlb, vma) do { } while (0)
@@ -8,4 +8,4 @@
 
 #include <asm-generic/tlb.h>
 
-#endif
+#endif /* ASM_X86__TLB_H */
index 35c76ceb9f4055eb548da359319a687467e73f66..ef68b76dc3c5c32f0ee2f24a1ecfec5725bba003 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_TLBFLUSH_H
-#define _ASM_X86_TLBFLUSH_H
+#ifndef ASM_X86__TLBFLUSH_H
+#define ASM_X86__TLBFLUSH_H
 
 #include <linux/mm.h>
 #include <linux/sched.h>
@@ -165,4 +165,4 @@ static inline void flush_tlb_kernel_range(unsigned long start,
        flush_tlb_all();
 }
 
-#endif /* _ASM_X86_TLBFLUSH_H */
+#endif /* ASM_X86__TLBFLUSH_H */
index 90ac7718469a5b416bfd90350b24ade716698925..7eca9bc022b2dd40568f6ff963dcd271a17de616 100644 (file)
@@ -22,8 +22,8 @@
  *
  * Send feedback to <colpatch@us.ibm.com>
  */
-#ifndef _ASM_X86_TOPOLOGY_H
-#define _ASM_X86_TOPOLOGY_H
+#ifndef ASM_X86__TOPOLOGY_H
+#define ASM_X86__TOPOLOGY_H
 
 #ifdef CONFIG_X86_32
 # ifdef CONFIG_X86_HT
@@ -255,4 +255,4 @@ static inline void set_mp_bus_to_node(int busnum, int node)
 }
 #endif
 
-#endif /* _ASM_X86_TOPOLOGY_H */
+#endif /* ASM_X86__TOPOLOGY_H */
index b156b08d0131a895b4b3d3a7034be45650220e16..0406bbd898a9601efbb5af853340712ed53e19a9 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __TRAMPOLINE_HEADER
-#define __TRAMPOLINE_HEADER
+#ifndef ASM_X86__TRAMPOLINE_H
+#define ASM_X86__TRAMPOLINE_H
 
 #ifndef __ASSEMBLY__
 
@@ -18,4 +18,4 @@ extern unsigned long setup_trampoline(void);
 
 #endif /* __ASSEMBLY__ */
 
-#endif /* __TRAMPOLINE_HEADER */
+#endif /* ASM_X86__TRAMPOLINE_H */
index a4b65a71bd6609e46f3da39969b522fa4958f0da..2ccebc6fb0b0143c9605ab548662718dacb8b97d 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_TRAPS_H
-#define _ASM_X86_TRAPS_H
+#ifndef ASM_X86__TRAPS_H
+#define ASM_X86__TRAPS_H
 
 /* Common in X86_32 and X86_64 */
 asmlinkage void divide_error(void);
@@ -51,6 +51,8 @@ void do_spurious_interrupt_bug(struct pt_regs *, long);
 unsigned long patch_espfix_desc(unsigned long, unsigned long);
 asmlinkage void math_emulate(long);
 
+void do_page_fault(struct pt_regs *regs, unsigned long error_code);
+
 #else /* CONFIG_X86_32 */
 
 asmlinkage void double_fault(void);
@@ -62,5 +64,7 @@ asmlinkage void do_coprocessor_error(struct pt_regs *);
 asmlinkage void do_simd_coprocessor_error(struct pt_regs *);
 asmlinkage void do_spurious_interrupt_bug(struct pt_regs *);
 
+asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code);
+
 #endif /* CONFIG_X86_32 */
-#endif /* _ASM_X86_TRAPS_H */
+#endif /* ASM_X86__TRAPS_H */
index cb6f6ee45b8f858921ad4cfbcaf1f3f0d6f886a2..ad0f5c41e78cde2ba21c653cc4a159faed9e27d7 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * x86 TSC related functions
  */
-#ifndef _ASM_X86_TSC_H
-#define _ASM_X86_TSC_H
+#ifndef ASM_X86__TSC_H
+#define ASM_X86__TSC_H
 
 #include <asm/processor.h>
 
@@ -59,4 +59,4 @@ extern void check_tsc_sync_target(void);
 
 extern int notsc_setup(char *);
 
-#endif
+#endif /* ASM_X86__TSC_H */
index 1ac80cd9acf8599a143ce5cf98913b91a668eda7..e78b52e17444ac245618369c52d34514805481f9 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_TYPES_H
-#define _ASM_X86_TYPES_H
+#ifndef ASM_X86__TYPES_H
+#define ASM_X86__TYPES_H
 
 #include <asm-generic/int-ll64.h>
 
@@ -33,4 +33,4 @@ typedef u32 dma_addr_t;
 #endif /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 
-#endif
+#endif /* ASM_X86__TYPES_H */
index 5f702d1d52184424941d3238ee82597c9f05ce37..48ebc0ad40ec17b66b700812c5c4792662227a8f 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_UACCES_H_
-#define _ASM_UACCES_H_
+#ifndef ASM_X86__UACCESS_H
+#define ASM_X86__UACCESS_H
 /*
  * User space memory access functions
  */
@@ -450,5 +450,5 @@ extern struct movsl_mask {
 # include "uaccess_64.h"
 #endif
 
-#endif
+#endif /* ASM_X86__UACCESS_H */
 
index 6fdef39a0bcb849d86e3bb0e1ade448694d21cdb..6b5b57d9c6d1f9ee55cf15cebf75090696c63f45 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __i386_UACCESS_H
-#define __i386_UACCESS_H
+#ifndef ASM_X86__UACCESS_32_H
+#define ASM_X86__UACCESS_32_H
 
 /*
  * User space memory access functions
@@ -215,4 +215,4 @@ long strnlen_user(const char __user *str, long n);
 unsigned long __must_check clear_user(void __user *mem, unsigned long len);
 unsigned long __must_check __clear_user(void __user *mem, unsigned long len);
 
-#endif /* __i386_UACCESS_H */
+#endif /* ASM_X86__UACCESS_32_H */
index 45806d60bcbedc0fb51208508fc0b0d5b991d04b..c96c1f5d07a2c88e4f5ca547ea0f7154ac68583c 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __X86_64_UACCESS_H
-#define __X86_64_UACCESS_H
+#ifndef ASM_X86__UACCESS_64_H
+#define ASM_X86__UACCESS_64_H
 
 /*
  * User space memory access functions
@@ -199,4 +199,4 @@ static inline int __copy_from_user_inatomic_nocache(void *dst,
 unsigned long
 copy_user_handle_tail(char *to, char *from, unsigned len, unsigned zerorest);
 
-#endif /* __X86_64_UACCESS_H */
+#endif /* ASM_X86__UACCESS_64_H */
index 50a79f7fcde9e42f85fe825553b3efbd60791371..9948dd328084ef66461d2dc92c996235fc78eb5e 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_UCONTEXT_H
-#define _ASM_X86_UCONTEXT_H
+#ifndef ASM_X86__UCONTEXT_H
+#define ASM_X86__UCONTEXT_H
 
 struct ucontext {
        unsigned long     uc_flags;
@@ -9,4 +9,4 @@ struct ucontext {
        sigset_t          uc_sigmask;   /* mask last for extensibility */
 };
 
-#endif /* _ASM_X86_UCONTEXT_H */
+#endif /* ASM_X86__UCONTEXT_H */
index a7bd416b4763832f0a9851df49e92c938b8c5232..59dcdec37160a02127780c1b7f9a76743c2041e0 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_UNALIGNED_H
-#define _ASM_X86_UNALIGNED_H
+#ifndef ASM_X86__UNALIGNED_H
+#define ASM_X86__UNALIGNED_H
 
 /*
  * The x86 can do unaligned accesses itself.
@@ -11,4 +11,4 @@
 #define get_unaligned __get_unaligned_le
 #define put_unaligned __put_unaligned_le
 
-#endif /* _ASM_X86_UNALIGNED_H */
+#endif /* ASM_X86__UNALIGNED_H */
index d7394673b772442677ed3ec7063a4ea384ad7b62..017f4a87c9132bbce98f194b55d80c95ea3bfd65 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_I386_UNISTD_H_
-#define _ASM_I386_UNISTD_H_
+#ifndef ASM_X86__UNISTD_32_H
+#define ASM_X86__UNISTD_32_H
 
 /*
  * This file contains the system call numbers.
 #endif
 
 #endif /* __KERNEL__ */
-#endif /* _ASM_I386_UNISTD_H_ */
+#endif /* ASM_X86__UNISTD_32_H */
index 3a341d791792ad41999893f7034e529cce28e880..ace83f1f678730134569f1efb3656a1d869156d4 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_64_UNISTD_H_
-#define _ASM_X86_64_UNISTD_H_
+#ifndef ASM_X86__UNISTD_64_H
+#define ASM_X86__UNISTD_64_H
 
 #ifndef __SYSCALL
 #define __SYSCALL(a, b)
@@ -690,4 +690,4 @@ __SYSCALL(__NR_inotify_init1, sys_inotify_init1)
 #define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
 #endif /* __KERNEL__ */
 
-#endif /* _ASM_X86_64_UNISTD_H_ */
+#endif /* ASM_X86__UNISTD_64_H */
index 8b064bd9c5535fa741c404b6e202445a8a9a003b..a2151567db44388a2465bc32924f7399942a821d 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_UNWIND_H
-#define _ASM_X86_UNWIND_H
+#ifndef ASM_X86__UNWIND_H
+#define ASM_X86__UNWIND_H
 
 #define UNW_PC(frame) ((void)(frame), 0UL)
 #define UNW_SP(frame) ((void)(frame), 0UL)
@@ -10,4 +10,4 @@ static inline int arch_unw_user_mode(const void *info)
        return 0;
 }
 
-#endif /* _ASM_X86_UNWIND_H */
+#endif /* ASM_X86__UNWIND_H */
index a3d91004787924876ea3dd0a137c5c710b7f0051..aa66c1857f06580e80160b5f8c4f1a1d0495b1df 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef USER32_H
-#define USER32_H 1
+#ifndef ASM_X86__USER32_H
+#define ASM_X86__USER32_H
 
 /* IA32 compatible user structures for ptrace.
  * These should be used for 32bit coredumps too. */
@@ -67,4 +67,4 @@ struct user32 {
 };
 
 
-#endif
+#endif /* ASM_X86__USER32_H */
index d6e51edc259d909dd78035b6de1775861a86ead1..e0fe2f55f1a6c736bcc2e568b9f355c50ede638c 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _I386_USER_H
-#define _I386_USER_H
+#ifndef ASM_X86__USER_32_H
+#define ASM_X86__USER_32_H
 
 #include <asm/page.h>
 /* Core file format: The core file is written in such a way that gdb
@@ -128,4 +128,4 @@ struct user{
 #define HOST_TEXT_START_ADDR (u.start_code)
 #define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
 
-#endif /* _I386_USER_H */
+#endif /* ASM_X86__USER_32_H */
index 6037b634c77fd374ae744b2816e2c4765ad7ec4a..38b5799863b455ecd911ceb23685a9ec5bcde74b 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _X86_64_USER_H
-#define _X86_64_USER_H
+#ifndef ASM_X86__USER_64_H
+#define ASM_X86__USER_64_H
 
 #include <asm/types.h>
 #include <asm/page.h>
@@ -134,4 +134,4 @@ struct user {
 #define HOST_TEXT_START_ADDR (u.start_code)
 #define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
 
-#endif /* _X86_64_USER_H */
+#endif /* ASM_X86__USER_64_H */
index aa73362ff5dff48d17c4c36a6339dcb22fe0d3bf..7cd6d7ec1308fe523811d462865951a8667d7ab0 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_BIOS_H
-#define _ASM_X86_BIOS_H
+#ifndef ASM_X86__UV__BIOS_H
+#define ASM_X86__UV__BIOS_H
 
 /*
  * BIOS layer definitions.
@@ -65,4 +65,4 @@ x86_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
                   unsigned long *drift_info);
 extern const char *x86_bios_strerror(long status);
 
-#endif /* _ASM_X86_BIOS_H */
+#endif /* ASM_X86__UV__BIOS_H */
index 610b6b308e93a005ff98753ea3d8586b131202ab..77153fb18f5e085c5b518cdee6e27a587d01a938 100644 (file)
@@ -8,8 +8,8 @@
  * Copyright (C) 2008 Silicon Graphics, Inc. All rights reserved.
  */
 
-#ifndef __ASM_X86_UV_BAU__
-#define __ASM_X86_UV_BAU__
+#ifndef ASM_X86__UV__UV_BAU_H
+#define ASM_X86__UV__UV_BAU_H
 
 #include <linux/bitmap.h>
 #define BITSPERBYTE 8
@@ -329,4 +329,4 @@ extern int uv_flush_tlb_others(cpumask_t *, struct mm_struct *, unsigned long);
 extern void uv_bau_message_intr1(void);
 extern void uv_bau_timeout_intr1(void);
 
-#endif /* __ASM_X86_UV_BAU__ */
+#endif /* ASM_X86__UV__UV_BAU_H */
index a4ef26e5850bb445e5dfa5493b1778ee85feb771..bdb5b01afbf591d66f5b1ec87ee859886459f594 100644 (file)
@@ -8,8 +8,8 @@
  * Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved.
  */
 
-#ifndef __ASM_X86_UV_HUB_H__
-#define __ASM_X86_UV_HUB_H__
+#ifndef ASM_X86__UV__UV_HUB_H
+#define ASM_X86__UV__UV_HUB_H
 
 #include <linux/numa.h>
 #include <linux/percpu.h>
@@ -350,5 +350,5 @@ static inline int uv_num_possible_blades(void)
        return uv_possible_blades;
 }
 
-#endif /* __ASM_X86_UV_HUB__ */
+#endif /* ASM_X86__UV__UV_HUB_H */
 
index 151fd7fcb809138d3454c50f023de8b1b49d5335..8b03d89d2459e8f3664bf1dbca34593b40457407 100644 (file)
@@ -8,8 +8,8 @@
  * Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved.
  */
 
-#ifndef __ASM_X86_UV_MMRS__
-#define __ASM_X86_UV_MMRS__
+#ifndef ASM_X86__UV__UV_MMRS_H
+#define ASM_X86__UV__UV_MMRS_H
 
 #define UV_MMR_ENABLE          (1UL << 63)
 
@@ -1292,4 +1292,4 @@ union uvh_si_alias2_overlay_config_u {
 };
 
 
-#endif /* __ASM_X86_UV_MMRS__ */
+#endif /* ASM_X86__UV__UV_MMRS_H */
index 8e18fb80f5e641ac3683b8c84c68cb511c4ab30f..4ab320913ea3abcef82fc8313127501249a201bb 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_VDSO_H
-#define _ASM_X86_VDSO_H        1
+#ifndef ASM_X86__VDSO_H
+#define ASM_X86__VDSO_H
 
 #ifdef CONFIG_X86_64
 extern const char VDSO64_PRELINK[];
@@ -44,4 +44,4 @@ extern const char vdso32_int80_start, vdso32_int80_end;
 extern const char vdso32_syscall_start, vdso32_syscall_end;
 extern const char vdso32_sysenter_start, vdso32_sysenter_end;
 
-#endif /* asm-x86/vdso.h */
+#endif /* ASM_X86__VDSO_H */
index 0ccf804377e600b7014a7247f964b8b83a4dd058..b9e493d07d07a1478ec8d42538cf55fe54e3b970 100644 (file)
@@ -4,8 +4,8 @@
  *     (c) 1998 Martin Mares <mj@ucw.cz>
  */
 
-#ifndef _LINUX_ASM_VGA_H_
-#define _LINUX_ASM_VGA_H_
+#ifndef ASM_X86__VGA_H
+#define ASM_X86__VGA_H
 
 /*
  *     On the PC, we can just recalculate addresses and then
@@ -17,4 +17,4 @@
 #define vga_readb(x) (*(x))
 #define vga_writeb(x, y) (*(y) = (x))
 
-#endif
+#endif /* ASM_X86__VGA_H */
index 3301f092934291427d1505c056b636cdd2fe8148..38fd133640211790b4dfe3e0b31a7f171d52e88c 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_VGTOD_H
-#define _ASM_VGTOD_H 1
+#ifndef ASM_X86__VGTOD_H
+#define ASM_X86__VGTOD_H
 
 #include <asm/vsyscall.h>
 #include <linux/clocksource.h>
@@ -26,4 +26,4 @@ extern struct vsyscall_gtod_data __vsyscall_gtod_data
 __section_vsyscall_gtod_data;
 extern struct vsyscall_gtod_data vsyscall_gtod_data;
 
-#endif
+#endif /* ASM_X86__VGTOD_H */
index 995258831b7f8dbf5a97b37315a0676eda7f8426..9627a8fe84e9275a28728fd81158ff465ac1cba9 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __I386_SGI_COBALT_H
-#define __I386_SGI_COBALT_H
+#ifndef ASM_X86__VISWS__COBALT_H
+#define ASM_X86__VISWS__COBALT_H
 
 #include <asm/fixmap.h>
 
@@ -122,4 +122,4 @@ extern char visws_board_type;
 
 extern char visws_board_rev;
 
-#endif /* __I386_SGI_COBALT_H */
+#endif /* ASM_X86__VISWS__COBALT_H */
index dfcd4f07ab85b9e6a1c839de753bb242eb8076c4..b36d3b378c6353dd2c62811ae8d94afafa8e55fd 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __I386_SGI_LITHIUM_H
-#define __I386_SGI_LITHIUM_H
+#ifndef ASM_X86__VISWS__LITHIUM_H
+#define ASM_X86__VISWS__LITHIUM_H
 
 #include <asm/fixmap.h>
 
@@ -49,5 +49,5 @@ static inline unsigned short li_pcib_read16(unsigned long reg)
        return *((volatile unsigned short *)(LI_PCIB_VADDR+reg));
 }
 
-#endif
+#endif /* ASM_X86__VISWS__LITHIUM_H */
 
index 83ea4f46e41984b2ecad1800a248dd3301675aae..61c938045ec95175dc74f81a9b414defb731bc03 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __I386_SGI_PIIX_H
-#define __I386_SGI_PIIX_H
+#ifndef ASM_X86__VISWS__PIIX4_H
+#define ASM_X86__VISWS__PIIX4_H
 
 /*
  * PIIX4 as used on SGI Visual Workstations
  */
 #define        PIIX_GPI_STPCLK         0x4     // STPCLK signal routed back in
 
-#endif
+#endif /* ASM_X86__VISWS__PIIX4_H */
index 5ce351325e011c72721d1f58c0b6e2d6f16f77e7..998bd18eb737d5911b8e3ffa62725957aae9a2d5 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _LINUX_VM86_H
-#define _LINUX_VM86_H
+#ifndef ASM_X86__VM86_H
+#define ASM_X86__VM86_H
 
 /*
  * I'm guessing at the VIF/VIP flag usage, but hope that this is how
@@ -205,4 +205,4 @@ static inline int handle_vm86_trap(struct kernel_vm86_regs *a, long b, int c)
 
 #endif /* __KERNEL__ */
 
-#endif
+#endif /* ASM_X86__VM86_H */
index c3118c3851565c9ae7a87e0d98e355fbf3efdc7a..b2d39e6a08b73a0aec01c226e2a78c2e9ed02652 100644 (file)
@@ -22,8 +22,8 @@
  *
  */
 
-#ifndef __VMI_TIME_H
-#define __VMI_TIME_H
+#ifndef ASM_X86__VMI_TIME_H
+#define ASM_X86__VMI_TIME_H
 
 /*
  * Raw VMI call indices for timer functions
@@ -95,4 +95,4 @@ extern void __devinit vmi_time_ap_init(void);
 
 #define CONFIG_VMI_ALARM_HZ    100
 
-#endif
+#endif /* ASM_X86__VMI_TIME_H */
index 6b66ff905af0408ee9ff586c4fe49dfc001c9af1..dcd4682413de06bb0c9e41126fbb4f6d8597b104 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_64_VSYSCALL_H_
-#define _ASM_X86_64_VSYSCALL_H_
+#ifndef ASM_X86__VSYSCALL_H
+#define ASM_X86__VSYSCALL_H
 
 enum vsyscall_num {
        __NR_vgettimeofday,
@@ -41,4 +41,4 @@ extern void map_vsyscall(void);
 
 #endif /* __KERNEL__ */
 
-#endif /* _ASM_X86_64_VSYSCALL_H_ */
+#endif /* ASM_X86__VSYSCALL_H */
index 8ded7472002419e1067a663799dff272623190d0..8151f5b8b6cb577588b15f8cb0ef9eb1f42da451 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __XEN_EVENTS_H
-#define __XEN_EVENTS_H
+#ifndef ASM_X86__XEN__EVENTS_H
+#define ASM_X86__XEN__EVENTS_H
 
 enum ipi_vector {
        XEN_RESCHEDULE_VECTOR,
@@ -21,4 +21,4 @@ static inline void xen_do_IRQ(int irq, struct pt_regs *regs)
        do_IRQ(regs);
 }
 
-#endif /* __XEN_EVENTS_H */
+#endif /* ASM_X86__XEN__EVENTS_H */
index 2444d4593a3babf29547dae15fc03fdd876f088c..c4baab4d2b68d9f94b10839f6941658f3923519d 100644 (file)
@@ -1,7 +1,7 @@
-#ifndef __XEN_GRANT_TABLE_H
-#define __XEN_GRANT_TABLE_H
+#ifndef ASM_X86__XEN__GRANT_TABLE_H
+#define ASM_X86__XEN__GRANT_TABLE_H
 
 #define xen_alloc_vm_area(size)        alloc_vm_area(size)
 #define xen_free_vm_area(area) free_vm_area(area)
 
-#endif /* __XEN_GRANT_TABLE_H */
+#endif /* ASM_X86__XEN__GRANT_TABLE_H */
index 91cb7fd5c1234be0f549b44f8a93208c7fedd92d..44f4259bee3f0d72a9de91a90c6adfaf0bec6abf 100644 (file)
@@ -30,8 +30,8 @@
  * IN THE SOFTWARE.
  */
 
-#ifndef __HYPERCALL_H__
-#define __HYPERCALL_H__
+#ifndef ASM_X86__XEN__HYPERCALL_H
+#define ASM_X86__XEN__HYPERCALL_H
 
 #include <linux/errno.h>
 #include <linux/string.h>
@@ -524,4 +524,4 @@ MULTI_stack_switch(struct multicall_entry *mcl,
        mcl->args[1] = esp;
 }
 
-#endif /* __HYPERCALL_H__ */
+#endif /* ASM_X86__XEN__HYPERCALL_H */
index 04ee0610014ab69e14b602487a197e5536fa9813..0ef3a88b869df8c67ec6ec64021b664d5aec71a7 100644 (file)
@@ -30,8 +30,8 @@
  * IN THE SOFTWARE.
  */
 
-#ifndef __HYPERVISOR_H__
-#define __HYPERVISOR_H__
+#ifndef ASM_X86__XEN__HYPERVISOR_H
+#define ASM_X86__XEN__HYPERVISOR_H
 
 #include <linux/types.h>
 #include <linux/kernel.h>
@@ -69,4 +69,4 @@ u64 jiffies_to_st(unsigned long jiffies);
 
 #define is_running_on_xen()    (xen_start_info ? 1 : 0)
 
-#endif /* __HYPERVISOR_H__ */
+#endif /* ASM_X86__XEN__HYPERVISOR_H */
index 9d810f2538a2227083bbe8b6bc7a7b753c9add7b..d077bba96da9753d4db566f511575ea8fe0b23db 100644 (file)
@@ -6,8 +6,8 @@
  * Copyright (c) 2004, K A Fraser
  */
 
-#ifndef __ASM_X86_XEN_INTERFACE_H
-#define __ASM_X86_XEN_INTERFACE_H
+#ifndef ASM_X86__XEN__INTERFACE_H
+#define ASM_X86__XEN__INTERFACE_H
 
 #ifdef __XEN__
 #define __DEFINE_GUEST_HANDLE(name, type) \
@@ -172,4 +172,4 @@ DEFINE_GUEST_HANDLE_STRUCT(vcpu_guest_context);
 #define XEN_CPUID          XEN_EMULATE_PREFIX "cpuid"
 #endif
 
-#endif /* __ASM_X86_XEN_INTERFACE_H */
+#endif /* ASM_X86__XEN__INTERFACE_H */
index d8ac41d5db864cfb8ca560cde4efa23fcf823ea6..08167e19fc66cdefbdc3e50c3457750a8c324115 100644 (file)
@@ -6,8 +6,8 @@
  * Copyright (c) 2004, K A Fraser
  */
 
-#ifndef __ASM_X86_XEN_INTERFACE_32_H
-#define __ASM_X86_XEN_INTERFACE_32_H
+#ifndef ASM_X86__XEN__INTERFACE_32_H
+#define ASM_X86__XEN__INTERFACE_32_H
 
 
 /*
@@ -94,4 +94,4 @@ typedef struct xen_callback xen_callback_t;
 #define xen_pfn_to_cr3(pfn) (((unsigned)(pfn) << 12) | ((unsigned)(pfn) >> 20))
 #define xen_cr3_to_pfn(cr3) (((unsigned)(cr3) >> 12) | ((unsigned)(cr3) << 20))
 
-#endif /* __ASM_X86_XEN_INTERFACE_32_H */
+#endif /* ASM_X86__XEN__INTERFACE_32_H */
index 842266ce96e66d0c1ef2ca6aa9dacce59ce72b02..046c0f1e01d4095574ce63716f34f104bfc1d8fc 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_X86_XEN_INTERFACE_64_H
-#define __ASM_X86_XEN_INTERFACE_64_H
+#ifndef ASM_X86__XEN__INTERFACE_64_H
+#define ASM_X86__XEN__INTERFACE_64_H
 
 /*
  * 64-bit segment selectors
@@ -156,4 +156,4 @@ typedef unsigned long xen_callback_t;
 #endif /* !__ASSEMBLY__ */
 
 
-#endif /* __ASM_X86_XEN_INTERFACE_64_H */
+#endif /* ASM_X86__XEN__INTERFACE_64_H */
index 7b3835d3b77d9b910228fc0362b19747eb441e26..c50185dccec192bdef7e0d936863d5503cc304d5 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __XEN_PAGE_H
-#define __XEN_PAGE_H
+#ifndef ASM_X86__XEN__PAGE_H
+#define ASM_X86__XEN__PAGE_H
 
 #include <linux/pfn.h>
 
@@ -162,4 +162,4 @@ xmaddr_t arbitrary_virt_to_machine(void *address);
 void make_lowmem_page_readonly(void *vaddr);
 void make_lowmem_page_readwrite(void *vaddr);
 
-#endif /* __XEN_PAGE_H */
+#endif /* ASM_X86__XEN__PAGE_H */
diff --git a/include/crypto/internal/rng.h b/include/crypto/internal/rng.h
new file mode 100644 (file)
index 0000000..8969733
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * RNG: Random Number Generator  algorithms under the crypto API
+ *
+ * Copyright (c) 2008 Neil Horman <nhorman@tuxdriver.com>
+ *
+ * This program 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.
+ *
+ */
+
+#ifndef _CRYPTO_INTERNAL_RNG_H
+#define _CRYPTO_INTERNAL_RNG_H
+
+#include <crypto/algapi.h>
+#include <crypto/rng.h>
+
+extern const struct crypto_type crypto_rng_type;
+
+static inline void *crypto_rng_ctx(struct crypto_rng *tfm)
+{
+       return crypto_tfm_ctx(&tfm->base);
+}
+
+#endif
index ccc32bad9a890df12d3662401a4de87e60cdbaff..2ba42cd7d6aa4c4fa708ba2733b6a20a59c3c526 100644 (file)
@@ -15,7 +15,6 @@
 
 #include <crypto/algapi.h>
 #include <crypto/skcipher.h>
-#include <linux/init.h>
 #include <linux/types.h>
 
 struct rtattr;
@@ -65,11 +64,6 @@ void skcipher_geniv_free(struct crypto_instance *inst);
 int skcipher_geniv_init(struct crypto_tfm *tfm);
 void skcipher_geniv_exit(struct crypto_tfm *tfm);
 
-int __init eseqiv_module_init(void);
-void __exit eseqiv_module_exit(void);
-int __init chainiv_module_init(void);
-void chainiv_module_exit(void);
-
 static inline struct crypto_ablkcipher *skcipher_geniv_cipher(
        struct crypto_ablkcipher *geniv)
 {
diff --git a/include/crypto/rng.h b/include/crypto/rng.h
new file mode 100644 (file)
index 0000000..c93f9b9
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * RNG: Random Number Generator  algorithms under the crypto API
+ *
+ * Copyright (c) 2008 Neil Horman <nhorman@tuxdriver.com>
+ *
+ * This program 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.
+ *
+ */
+
+#ifndef _CRYPTO_RNG_H
+#define _CRYPTO_RNG_H
+
+#include <linux/crypto.h>
+
+extern struct crypto_rng *crypto_default_rng;
+
+int crypto_get_default_rng(void);
+void crypto_put_default_rng(void);
+
+static inline struct crypto_rng *__crypto_rng_cast(struct crypto_tfm *tfm)
+{
+       return (struct crypto_rng *)tfm;
+}
+
+static inline struct crypto_rng *crypto_alloc_rng(const char *alg_name,
+                                                 u32 type, u32 mask)
+{
+       type &= ~CRYPTO_ALG_TYPE_MASK;
+       type |= CRYPTO_ALG_TYPE_RNG;
+       mask |= CRYPTO_ALG_TYPE_MASK;
+
+       return __crypto_rng_cast(crypto_alloc_base(alg_name, type, mask));
+}
+
+static inline struct crypto_tfm *crypto_rng_tfm(struct crypto_rng *tfm)
+{
+       return &tfm->base;
+}
+
+static inline struct rng_alg *crypto_rng_alg(struct crypto_rng *tfm)
+{
+       return &crypto_rng_tfm(tfm)->__crt_alg->cra_rng;
+}
+
+static inline struct rng_tfm *crypto_rng_crt(struct crypto_rng *tfm)
+{
+       return &crypto_rng_tfm(tfm)->crt_rng;
+}
+
+static inline void crypto_free_rng(struct crypto_rng *tfm)
+{
+       crypto_free_tfm(crypto_rng_tfm(tfm));
+}
+
+static inline int crypto_rng_get_bytes(struct crypto_rng *tfm,
+                                      u8 *rdata, unsigned int dlen)
+{
+       return crypto_rng_crt(tfm)->rng_gen_random(tfm, rdata, dlen);
+}
+
+static inline int crypto_rng_reset(struct crypto_rng *tfm,
+                                  u8 *seed, unsigned int slen)
+{
+       return crypto_rng_crt(tfm)->rng_reset(tfm, seed, slen);
+}
+
+static inline int crypto_rng_seedsize(struct crypto_rng *tfm)
+{
+       return crypto_rng_alg(tfm)->seedsize;
+}
+
+#endif
index b68ec09399be562110b92b0903a26ca058875e0e..31474e89c59adfd241dfd64db4fbdc1a4a8bc779 100644 (file)
@@ -180,6 +180,7 @@ unifdef-y += audit.h
 unifdef-y += auto_fs.h
 unifdef-y += auxvec.h
 unifdef-y += binfmts.h
+unifdef-y += blktrace_api.h
 unifdef-y += capability.h
 unifdef-y += capi.h
 unifdef-y += cciss_ioctl.h
index 8a12d718c16931892d7842a9e6e3c3e6020b2443..be00973d1a8cd0e01f8b0506fded02472ea80af7 100644 (file)
@@ -88,6 +88,7 @@ enum {
        ATA_ID_DLF              = 128,
        ATA_ID_CSFO             = 129,
        ATA_ID_CFA_POWER        = 160,
+       ATA_ID_ROT_SPEED        = 217,
        ATA_ID_PIO4             = (1 << 1),
 
        ATA_ID_SERNO_LEN        = 20,
@@ -667,6 +668,15 @@ static inline int ata_id_has_dword_io(const u16 *id)
        return 0;
 }
 
+static inline int ata_id_has_unload(const u16 *id)
+{
+       if (ata_id_major_version(id) >= 7 &&
+           (id[ATA_ID_CFSSE] & 0xC000) == 0x4000 &&
+           id[ATA_ID_CFSSE] & (1 << 13))
+               return 1;
+       return 0;
+}
+
 static inline int ata_id_current_chs_valid(const u16 *id)
 {
        /* For ATA-1 devices, if the INITIALIZE DEVICE PARAMETERS command
@@ -691,6 +701,11 @@ static inline int ata_id_is_cfa(const u16 *id)
        return 0;
 }
 
+static inline int ata_id_is_ssd(const u16 *id)
+{
+       return id[ATA_ID_ROT_SPEED] == 0x01;
+}
+
 static inline int ata_drive_40wire(const u16 *dev_id)
 {
        if (ata_id_is_sata(dev_id))
index 0933a14e641423f523d8ed7a56ef7f2a6b849e5c..ff5b4cf9e2da71abd05b5fac387322b24c75b911 100644 (file)
 
 #ifdef CONFIG_BLOCK
 
-/* Platforms may set this to teach the BIO layer about IOMMU hardware. */
 #include <asm/io.h>
 
-#if defined(BIO_VMERGE_MAX_SIZE) && defined(BIO_VMERGE_BOUNDARY)
-#define BIOVEC_VIRT_START_SIZE(x) (bvec_to_phys(x) & (BIO_VMERGE_BOUNDARY - 1))
-#define BIOVEC_VIRT_OVERSIZE(x)        ((x) > BIO_VMERGE_MAX_SIZE)
-#else
-#define BIOVEC_VIRT_START_SIZE(x)      0
-#define BIOVEC_VIRT_OVERSIZE(x)                0
-#endif
-
-#ifndef BIO_VMERGE_BOUNDARY
-#define BIO_VMERGE_BOUNDARY    0
-#endif
-
 #define BIO_DEBUG
 
 #ifdef BIO_DEBUG
@@ -88,25 +75,14 @@ struct bio {
        /* Number of segments in this BIO after
         * physical address coalescing is performed.
         */
-       unsigned short          bi_phys_segments;
-
-       /* Number of segments after physical and DMA remapping
-        * hardware coalescing is performed.
-        */
-       unsigned short          bi_hw_segments;
+       unsigned int            bi_phys_segments;
 
        unsigned int            bi_size;        /* residual I/O count */
 
-       /*
-        * To keep track of the max hw size, we account for the
-        * sizes of the first and last virtually mergeable segments
-        * in this bio
-        */
-       unsigned int            bi_hw_front_size;
-       unsigned int            bi_hw_back_size;
-
        unsigned int            bi_max_vecs;    /* max bvl_vecs we can hold */
 
+       unsigned int            bi_comp_cpu;    /* completion CPU */
+
        struct bio_vec          *bi_io_vec;     /* the actual vec list */
 
        bio_end_io_t            *bi_end_io;
@@ -126,11 +102,14 @@ struct bio {
 #define BIO_UPTODATE   0       /* ok after I/O completion */
 #define BIO_RW_BLOCK   1       /* RW_AHEAD set, and read/write would block */
 #define BIO_EOF                2       /* out-out-bounds error */
-#define BIO_SEG_VALID  3       /* nr_hw_seg valid */
+#define BIO_SEG_VALID  3       /* bi_phys_segments valid */
 #define BIO_CLONED     4       /* doesn't own data */
 #define BIO_BOUNCED    5       /* bio is a bounce bio */
 #define BIO_USER_MAPPED 6      /* contains user pages */
 #define BIO_EOPNOTSUPP 7       /* not supported */
+#define BIO_CPU_AFFINE 8       /* complete bio on same CPU as submitted */
+#define BIO_NULL_MAPPED 9      /* contains invalid user pages */
+#define BIO_FS_INTEGRITY 10    /* fs owns integrity data, not block layer */
 #define bio_flagged(bio, flag) ((bio)->bi_flags & (1 << (flag)))
 
 /*
@@ -144,18 +123,31 @@ struct bio {
 /*
  * bio bi_rw flags
  *
- * bit 0 -- read (not set) or write (set)
+ * bit 0 -- data direction
+ *     If not set, bio is a read from device. If set, it's a write to device.
  * bit 1 -- rw-ahead when set
  * bit 2 -- barrier
+ *     Insert a serialization point in the IO queue, forcing previously
+ *     submitted IO to be completed before this oen is issued.
  * bit 3 -- fail fast, don't want low level driver retries
  * bit 4 -- synchronous I/O hint: the block layer will unplug immediately
+ *     Note that this does NOT indicate that the IO itself is sync, just
+ *     that the block layer will not postpone issue of this IO by plugging.
+ * bit 5 -- metadata request
+ *     Used for tracing to differentiate metadata and data IO. May also
+ *     get some preferential treatment in the IO scheduler
+ * bit 6 -- discard sectors
+ *     Informs the lower level device that this range of sectors is no longer
+ *     used by the file system and may thus be freed by the device. Used
+ *     for flash based storage.
  */
-#define BIO_RW         0
-#define BIO_RW_AHEAD   1
+#define BIO_RW         0       /* Must match RW in req flags (blkdev.h) */
+#define BIO_RW_AHEAD   1       /* Must match FAILFAST in req flags */
 #define BIO_RW_BARRIER 2
 #define BIO_RW_FAILFAST        3
 #define BIO_RW_SYNC    4
 #define BIO_RW_META    5
+#define BIO_RW_DISCARD 6
 
 /*
  * upper 16 bits of bi_rw define the io priority of this bio
@@ -185,14 +177,15 @@ struct bio {
 #define bio_failfast(bio)      ((bio)->bi_rw & (1 << BIO_RW_FAILFAST))
 #define bio_rw_ahead(bio)      ((bio)->bi_rw & (1 << BIO_RW_AHEAD))
 #define bio_rw_meta(bio)       ((bio)->bi_rw & (1 << BIO_RW_META))
-#define bio_empty_barrier(bio) (bio_barrier(bio) && !(bio)->bi_size)
+#define bio_discard(bio)       ((bio)->bi_rw & (1 << BIO_RW_DISCARD))
+#define bio_empty_barrier(bio) (bio_barrier(bio) && !bio_has_data(bio) && !bio_discard(bio))
 
 static inline unsigned int bio_cur_sectors(struct bio *bio)
 {
        if (bio->bi_vcnt)
                return bio_iovec(bio)->bv_len >> 9;
-
-       return 0;
+       else /* dataless requests such as discard */
+               return bio->bi_size >> 9;
 }
 
 static inline void *bio_data(struct bio *bio)
@@ -236,8 +229,6 @@ static inline void *bio_data(struct bio *bio)
        ((bvec_to_phys((vec1)) + (vec1)->bv_len) == bvec_to_phys((vec2)))
 #endif
 
-#define BIOVEC_VIRT_MERGEABLE(vec1, vec2)      \
-       ((((bvec_to_phys((vec1)) + (vec1)->bv_len) | bvec_to_phys((vec2))) & (BIO_VMERGE_BOUNDARY - 1)) == 0)
 #define __BIO_SEG_BOUNDARY(addr1, addr2, mask) \
        (((addr1) | (mask)) == (((addr2) - 1) | (mask)))
 #define BIOVEC_SEG_BOUNDARY(q, b1, b2) \
@@ -319,15 +310,14 @@ struct bio_pair {
        atomic_t                        cnt;
        int                             error;
 };
-extern struct bio_pair *bio_split(struct bio *bi, mempool_t *pool,
-                                 int first_sectors);
-extern mempool_t *bio_split_pool;
+extern struct bio_pair *bio_split(struct bio *bi, int first_sectors);
 extern void bio_pair_release(struct bio_pair *dbio);
 
 extern struct bio_set *bioset_create(int, int);
 extern void bioset_free(struct bio_set *);
 
 extern struct bio *bio_alloc(gfp_t, int);
+extern struct bio *bio_kmalloc(gfp_t, int);
 extern struct bio *bio_alloc_bioset(gfp_t, int, struct bio_set *);
 extern void bio_put(struct bio *);
 extern void bio_free(struct bio *, struct bio_set *);
@@ -335,7 +325,6 @@ extern void bio_free(struct bio *, struct bio_set *);
 extern void bio_endio(struct bio *, int);
 struct request_queue;
 extern int bio_phys_segments(struct request_queue *, struct bio *);
-extern int bio_hw_segments(struct request_queue *, struct bio *);
 
 extern void __bio_clone(struct bio *, struct bio *);
 extern struct bio *bio_clone(struct bio *, gfp_t);
@@ -346,12 +335,14 @@ extern int bio_add_page(struct bio *, struct page *, unsigned int,unsigned int);
 extern int bio_add_pc_page(struct request_queue *, struct bio *, struct page *,
                           unsigned int, unsigned int);
 extern int bio_get_nr_vecs(struct block_device *);
+extern sector_t bio_sector_offset(struct bio *, unsigned short, unsigned int);
 extern struct bio *bio_map_user(struct request_queue *, struct block_device *,
-                               unsigned long, unsigned int, int);
+                               unsigned long, unsigned int, int, gfp_t);
 struct sg_iovec;
+struct rq_map_data;
 extern struct bio *bio_map_user_iov(struct request_queue *,
                                    struct block_device *,
-                                   struct sg_iovec *, int, int);
+                                   struct sg_iovec *, int, int, gfp_t);
 extern void bio_unmap_user(struct bio *);
 extern struct bio *bio_map_kern(struct request_queue *, void *, unsigned int,
                                gfp_t);
@@ -359,14 +350,24 @@ extern struct bio *bio_copy_kern(struct request_queue *, void *, unsigned int,
                                 gfp_t, int);
 extern void bio_set_pages_dirty(struct bio *bio);
 extern void bio_check_pages_dirty(struct bio *bio);
-extern struct bio *bio_copy_user(struct request_queue *, unsigned long, unsigned int, int);
-extern struct bio *bio_copy_user_iov(struct request_queue *, struct sg_iovec *,
-                                    int, int);
+extern struct bio *bio_copy_user(struct request_queue *, struct rq_map_data *,
+                                unsigned long, unsigned int, int, gfp_t);
+extern struct bio *bio_copy_user_iov(struct request_queue *,
+                                    struct rq_map_data *, struct sg_iovec *,
+                                    int, int, gfp_t);
 extern int bio_uncopy_user(struct bio *);
 void zero_fill_bio(struct bio *bio);
 extern struct bio_vec *bvec_alloc_bs(gfp_t, int, unsigned long *, struct bio_set *);
 extern unsigned int bvec_nr_vecs(unsigned short idx);
 
+/*
+ * Allow queuer to specify a completion CPU for this bio
+ */
+static inline void bio_set_completion_cpu(struct bio *bio, unsigned int cpu)
+{
+       bio->bi_comp_cpu = cpu;
+}
+
 /*
  * bio_set is used to allow other portions of the IO system to
  * allocate their own private memory pools for bio and iovec structures.
@@ -445,6 +446,14 @@ static inline char *__bio_kmap_irq(struct bio *bio, unsigned short idx,
        __bio_kmap_irq((bio), (bio)->bi_idx, (flags))
 #define bio_kunmap_irq(buf,flags)      __bio_kunmap_irq(buf, flags)
 
+/*
+ * Check whether this bio carries any data or not. A NULL bio is allowed.
+ */
+static inline int bio_has_data(struct bio *bio)
+{
+       return bio && bio->bi_io_vec != NULL;
+}
+
 #if defined(CONFIG_BLK_DEV_INTEGRITY)
 
 #define bip_vec_idx(bip, idx)  (&(bip->bip_vec[(idx)]))
@@ -458,14 +467,7 @@ static inline char *__bio_kmap_irq(struct bio *bio, unsigned short idx,
 #define bip_for_each_vec(bvl, bip, i)                                  \
        __bip_for_each_vec(bvl, bip, i, (bip)->bip_idx)
 
-static inline int bio_integrity(struct bio *bio)
-{
-#if defined(CONFIG_BLK_DEV_INTEGRITY)
-       return bio->bi_integrity != NULL;
-#else
-       return 0;
-#endif
-}
+#define bio_integrity(bio) (bio->bi_integrity != NULL)
 
 extern struct bio_integrity_payload *bio_integrity_alloc_bioset(struct bio *, gfp_t, unsigned int, struct bio_set *);
 extern struct bio_integrity_payload *bio_integrity_alloc(struct bio *, gfp_t, unsigned int);
index 53ea933cf60bde455e4abc0687e06da638641b8a..a92d9e4ea96e1a0a5af66bf21c6dbf155674e418 100644 (file)
@@ -16,7 +16,9 @@
 #include <linux/bio.h>
 #include <linux/module.h>
 #include <linux/stringify.h>
+#include <linux/gfp.h>
 #include <linux/bsg.h>
+#include <linux/smp.h>
 
 #include <asm/scatterlist.h>
 
@@ -54,7 +56,6 @@ enum rq_cmd_type_bits {
        REQ_TYPE_PM_SUSPEND,            /* suspend request */
        REQ_TYPE_PM_RESUME,             /* resume request */
        REQ_TYPE_PM_SHUTDOWN,           /* shutdown request */
-       REQ_TYPE_FLUSH,                 /* flush request */
        REQ_TYPE_SPECIAL,               /* driver defined type */
        REQ_TYPE_LINUX_BLOCK,           /* generic block layer message */
        /*
@@ -76,19 +77,18 @@ enum rq_cmd_type_bits {
  *
  */
 enum {
-       /*
-        * just examples for now
-        */
        REQ_LB_OP_EJECT = 0x40,         /* eject request */
-       REQ_LB_OP_FLUSH = 0x41,         /* flush device */
+       REQ_LB_OP_FLUSH = 0x41,         /* flush request */
+       REQ_LB_OP_DISCARD = 0x42,       /* discard sectors */
 };
 
 /*
- * request type modified bits. first three bits match BIO_RW* bits, important
+ * request type modified bits. first two bits match BIO_RW* bits, important
  */
 enum rq_flag_bits {
        __REQ_RW,               /* not set, read. set, write */
        __REQ_FAILFAST,         /* no low level driver retries */
+       __REQ_DISCARD,          /* request to discard sectors */
        __REQ_SORTED,           /* elevator knows about this request */
        __REQ_SOFTBARRIER,      /* may not be passed by ioscheduler */
        __REQ_HARDBARRIER,      /* may not be passed by drive either */
@@ -111,6 +111,7 @@ enum rq_flag_bits {
 };
 
 #define REQ_RW         (1 << __REQ_RW)
+#define REQ_DISCARD    (1 << __REQ_DISCARD)
 #define REQ_FAILFAST   (1 << __REQ_FAILFAST)
 #define REQ_SORTED     (1 << __REQ_SORTED)
 #define REQ_SOFTBARRIER        (1 << __REQ_SOFTBARRIER)
@@ -140,12 +141,14 @@ enum rq_flag_bits {
  */
 struct request {
        struct list_head queuelist;
-       struct list_head donelist;
+       struct call_single_data csd;
+       int cpu;
 
        struct request_queue *q;
 
        unsigned int cmd_flags;
        enum rq_cmd_type_bits cmd_type;
+       unsigned long atomic_flags;
 
        /* Maintain bio traversal state for part by part I/O submission.
         * hard_* are block layer internals, no driver should touch them!
@@ -190,13 +193,6 @@ struct request {
         */
        unsigned short nr_phys_segments;
 
-       /* Number of scatter-gather addr+len pairs after
-        * physical and DMA remapping hardware coalescing is performed.
-        * This is the number of scatter-gather entries the driver
-        * will actually have to deal with after DMA mapping is done.
-        */
-       unsigned short nr_hw_segments;
-
        unsigned short ioprio;
 
        void *special;
@@ -220,6 +216,8 @@ struct request {
        void *data;
        void *sense;
 
+       unsigned long deadline;
+       struct list_head timeout_list;
        unsigned int timeout;
        int retries;
 
@@ -233,6 +231,11 @@ struct request {
        struct request *next_rq;
 };
 
+static inline unsigned short req_get_ioprio(struct request *req)
+{
+       return req->ioprio;
+}
+
 /*
  * State information carried for REQ_TYPE_PM_SUSPEND and REQ_TYPE_PM_RESUME
  * requests. Some step values could eventually be made generic.
@@ -252,6 +255,7 @@ typedef void (request_fn_proc) (struct request_queue *q);
 typedef int (make_request_fn) (struct request_queue *q, struct bio *bio);
 typedef int (prep_rq_fn) (struct request_queue *, struct request *);
 typedef void (unplug_fn) (struct request_queue *);
+typedef int (prepare_discard_fn) (struct request_queue *, struct request *);
 
 struct bio_vec;
 struct bvec_merge_data {
@@ -265,6 +269,15 @@ typedef int (merge_bvec_fn) (struct request_queue *, struct bvec_merge_data *,
 typedef void (prepare_flush_fn) (struct request_queue *, struct request *);
 typedef void (softirq_done_fn)(struct request *);
 typedef int (dma_drain_needed_fn)(struct request *);
+typedef int (lld_busy_fn) (struct request_queue *q);
+
+enum blk_eh_timer_return {
+       BLK_EH_NOT_HANDLED,
+       BLK_EH_HANDLED,
+       BLK_EH_RESET_TIMER,
+};
+
+typedef enum blk_eh_timer_return (rq_timed_out_fn)(struct request *);
 
 enum blk_queue_state {
        Queue_down,
@@ -307,10 +320,13 @@ struct request_queue
        make_request_fn         *make_request_fn;
        prep_rq_fn              *prep_rq_fn;
        unplug_fn               *unplug_fn;
+       prepare_discard_fn      *prepare_discard_fn;
        merge_bvec_fn           *merge_bvec_fn;
        prepare_flush_fn        *prepare_flush_fn;
        softirq_done_fn         *softirq_done_fn;
+       rq_timed_out_fn         *rq_timed_out_fn;
        dma_drain_needed_fn     *dma_drain_needed;
+       lld_busy_fn             *lld_busy_fn;
 
        /*
         * Dispatch queue sorting
@@ -385,6 +401,10 @@ struct request_queue
        unsigned int            nr_sorted;
        unsigned int            in_flight;
 
+       unsigned int            rq_timeout;
+       struct timer_list       timeout;
+       struct list_head        timeout_list;
+
        /*
         * sg stuff
         */
@@ -421,6 +441,10 @@ struct request_queue
 #define QUEUE_FLAG_ELVSWITCH   8       /* don't use elevator, just do FIFO */
 #define QUEUE_FLAG_BIDI                9       /* queue supports bidi requests */
 #define QUEUE_FLAG_NOMERGES    10      /* disable merge attempts */
+#define QUEUE_FLAG_SAME_COMP   11      /* force complete on same CPU */
+#define QUEUE_FLAG_FAIL_IO     12      /* fake timeout */
+#define QUEUE_FLAG_STACKABLE   13      /* supports request stacking */
+#define QUEUE_FLAG_NONROT      14      /* non-rotational device (SSD) */
 
 static inline int queue_is_locked(struct request_queue *q)
 {
@@ -526,7 +550,10 @@ enum {
 #define blk_queue_tagged(q)    test_bit(QUEUE_FLAG_QUEUED, &(q)->queue_flags)
 #define blk_queue_stopped(q)   test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags)
 #define blk_queue_nomerges(q)  test_bit(QUEUE_FLAG_NOMERGES, &(q)->queue_flags)
+#define blk_queue_nonrot(q)    test_bit(QUEUE_FLAG_NONROT, &(q)->queue_flags)
 #define blk_queue_flushing(q)  ((q)->ordseq)
+#define blk_queue_stackable(q) \
+       test_bit(QUEUE_FLAG_STACKABLE, &(q)->queue_flags)
 
 #define blk_fs_request(rq)     ((rq)->cmd_type == REQ_TYPE_FS)
 #define blk_pc_request(rq)     ((rq)->cmd_type == REQ_TYPE_BLOCK_PC)
@@ -536,16 +563,18 @@ enum {
 #define blk_noretry_request(rq)        ((rq)->cmd_flags & REQ_FAILFAST)
 #define blk_rq_started(rq)     ((rq)->cmd_flags & REQ_STARTED)
 
-#define blk_account_rq(rq)     (blk_rq_started(rq) && blk_fs_request(rq))
+#define blk_account_rq(rq)     (blk_rq_started(rq) && (blk_fs_request(rq) || blk_discard_rq(rq))) 
 
 #define blk_pm_suspend_request(rq)     ((rq)->cmd_type == REQ_TYPE_PM_SUSPEND)
 #define blk_pm_resume_request(rq)      ((rq)->cmd_type == REQ_TYPE_PM_RESUME)
 #define blk_pm_request(rq)     \
        (blk_pm_suspend_request(rq) || blk_pm_resume_request(rq))
 
+#define blk_rq_cpu_valid(rq)   ((rq)->cpu != -1)
 #define blk_sorted_rq(rq)      ((rq)->cmd_flags & REQ_SORTED)
 #define blk_barrier_rq(rq)     ((rq)->cmd_flags & REQ_HARDBARRIER)
 #define blk_fua_rq(rq)         ((rq)->cmd_flags & REQ_FUA)
+#define blk_discard_rq(rq)     ((rq)->cmd_flags & REQ_DISCARD)
 #define blk_bidi_rq(rq)                ((rq)->next_rq != NULL)
 #define blk_empty_barrier(rq)  (blk_barrier_rq(rq) && blk_fs_request(rq) && !(rq)->hard_nr_sectors)
 /* rq->queuelist of dequeued request must be list_empty() */
@@ -592,7 +621,8 @@ static inline void blk_clear_queue_full(struct request_queue *q, int rw)
 #define RQ_NOMERGE_FLAGS       \
        (REQ_NOMERGE | REQ_STARTED | REQ_HARDBARRIER | REQ_SOFTBARRIER)
 #define rq_mergeable(rq)       \
-       (!((rq)->cmd_flags & RQ_NOMERGE_FLAGS) && blk_fs_request((rq)))
+       (!((rq)->cmd_flags & RQ_NOMERGE_FLAGS) && \
+        (blk_discard_rq(rq) || blk_fs_request((rq))))
 
 /*
  * q->prep_rq_fn return values
@@ -637,6 +667,12 @@ static inline void blk_queue_bounce(struct request_queue *q, struct bio **bio)
 }
 #endif /* CONFIG_MMU */
 
+struct rq_map_data {
+       struct page **pages;
+       int page_order;
+       int nr_entries;
+};
+
 struct req_iterator {
        int i;
        struct bio *bio;
@@ -664,6 +700,10 @@ extern void __blk_put_request(struct request_queue *, struct request *);
 extern struct request *blk_get_request(struct request_queue *, int, gfp_t);
 extern void blk_insert_request(struct request_queue *, struct request *, int, void *);
 extern void blk_requeue_request(struct request_queue *, struct request *);
+extern int blk_rq_check_limits(struct request_queue *q, struct request *rq);
+extern int blk_lld_busy(struct request_queue *q);
+extern int blk_insert_cloned_request(struct request_queue *q,
+                                    struct request *rq);
 extern void blk_plug_device(struct request_queue *);
 extern void blk_plug_device_unlocked(struct request_queue *);
 extern int blk_remove_plug(struct request_queue *);
@@ -705,11 +745,14 @@ extern void __blk_stop_queue(struct request_queue *q);
 extern void __blk_run_queue(struct request_queue *);
 extern void blk_run_queue(struct request_queue *);
 extern void blk_start_queueing(struct request_queue *);
-extern int blk_rq_map_user(struct request_queue *, struct request *, void __user *, unsigned long);
+extern int blk_rq_map_user(struct request_queue *, struct request *,
+                          struct rq_map_data *, void __user *, unsigned long,
+                          gfp_t);
 extern int blk_rq_unmap_user(struct bio *);
 extern int blk_rq_map_kern(struct request_queue *, struct request *, void *, unsigned int, gfp_t);
 extern int blk_rq_map_user_iov(struct request_queue *, struct request *,
-                              struct sg_iovec *, int, unsigned int);
+                              struct rq_map_data *, struct sg_iovec *, int,
+                              unsigned int, gfp_t);
 extern int blk_execute_rq(struct request_queue *, struct gendisk *,
                          struct request *, int);
 extern void blk_execute_rq_nowait(struct request_queue *, struct gendisk *,
@@ -750,12 +793,15 @@ extern int __blk_end_request(struct request *rq, int error,
 extern int blk_end_bidi_request(struct request *rq, int error,
                                unsigned int nr_bytes, unsigned int bidi_bytes);
 extern void end_request(struct request *, int);
-extern void end_queued_request(struct request *, int);
-extern void end_dequeued_request(struct request *, int);
 extern int blk_end_request_callback(struct request *rq, int error,
                                unsigned int nr_bytes,
                                int (drv_callback)(struct request *));
 extern void blk_complete_request(struct request *);
+extern void __blk_complete_request(struct request *);
+extern void blk_abort_request(struct request *);
+extern void blk_abort_queue(struct request_queue *);
+extern void blk_update_request(struct request *rq, int error,
+                              unsigned int nr_bytes);
 
 /*
  * blk_end_request() takes bytes instead of sectors as a complete size.
@@ -790,12 +836,16 @@ extern void blk_queue_update_dma_pad(struct request_queue *, unsigned int);
 extern int blk_queue_dma_drain(struct request_queue *q,
                               dma_drain_needed_fn *dma_drain_needed,
                               void *buf, unsigned int size);
+extern void blk_queue_lld_busy(struct request_queue *q, lld_busy_fn *fn);
 extern void blk_queue_segment_boundary(struct request_queue *, unsigned long);
 extern void blk_queue_prep_rq(struct request_queue *, prep_rq_fn *pfn);
 extern void blk_queue_merge_bvec(struct request_queue *, merge_bvec_fn *);
 extern void blk_queue_dma_alignment(struct request_queue *, int);
 extern void blk_queue_update_dma_alignment(struct request_queue *, int);
 extern void blk_queue_softirq_done(struct request_queue *, softirq_done_fn *);
+extern void blk_queue_set_discard(struct request_queue *, prepare_discard_fn *);
+extern void blk_queue_rq_timed_out(struct request_queue *, rq_timed_out_fn *);
+extern void blk_queue_rq_timeout(struct request_queue *, unsigned int);
 extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev);
 extern int blk_queue_ordered(struct request_queue *, unsigned, prepare_flush_fn *);
 extern int blk_do_ordered(struct request_queue *, struct request **);
@@ -837,6 +887,16 @@ static inline struct request *blk_map_queue_find_tag(struct blk_queue_tag *bqt,
 }
 
 extern int blkdev_issue_flush(struct block_device *, sector_t *);
+extern int blkdev_issue_discard(struct block_device *,
+                               sector_t sector, sector_t nr_sects, gfp_t);
+
+static inline int sb_issue_discard(struct super_block *sb,
+                                  sector_t block, sector_t nr_blocks)
+{
+       block <<= (sb->s_blocksize_bits - 9);
+       nr_blocks <<= (sb->s_blocksize_bits - 9);
+       return blkdev_issue_discard(sb->s_bdev, block, nr_blocks, GFP_KERNEL);
+}
 
 /*
 * command filter functions
@@ -874,6 +934,13 @@ static inline int queue_dma_alignment(struct request_queue *q)
        return q ? q->dma_alignment : 511;
 }
 
+static inline int blk_rq_aligned(struct request_queue *q, void *addr,
+                                unsigned int len)
+{
+       unsigned int alignment = queue_dma_alignment(q) | q->dma_pad_mask;
+       return !((unsigned long)addr & alignment) && !(len & alignment);
+}
+
 /* assumes size > 256 */
 static inline unsigned int blksize_bits(unsigned int size)
 {
@@ -900,7 +967,7 @@ static inline void put_dev_sector(Sector p)
 }
 
 struct work_struct;
-int kblockd_schedule_work(struct work_struct *work);
+int kblockd_schedule_work(struct request_queue *q, struct work_struct *work);
 void kblockd_flush_work(struct work_struct *work);
 
 #define MODULE_ALIAS_BLOCKDEV(major,minor) \
@@ -945,49 +1012,19 @@ struct blk_integrity {
 
 extern int blk_integrity_register(struct gendisk *, struct blk_integrity *);
 extern void blk_integrity_unregister(struct gendisk *);
-extern int blk_integrity_compare(struct block_device *, struct block_device *);
+extern int blk_integrity_compare(struct gendisk *, struct gendisk *);
 extern int blk_rq_map_integrity_sg(struct request *, struct scatterlist *);
 extern int blk_rq_count_integrity_sg(struct request *);
 
-static inline unsigned short blk_integrity_tuple_size(struct blk_integrity *bi)
-{
-       if (bi)
-               return bi->tuple_size;
-
-       return 0;
-}
-
-static inline struct blk_integrity *bdev_get_integrity(struct block_device *bdev)
+static inline
+struct blk_integrity *bdev_get_integrity(struct block_device *bdev)
 {
        return bdev->bd_disk->integrity;
 }
 
-static inline unsigned int bdev_get_tag_size(struct block_device *bdev)
+static inline struct blk_integrity *blk_get_integrity(struct gendisk *disk)
 {
-       struct blk_integrity *bi = bdev_get_integrity(bdev);
-
-       if (bi)
-               return bi->tag_size;
-
-       return 0;
-}
-
-static inline int bdev_integrity_enabled(struct block_device *bdev, int rw)
-{
-       struct blk_integrity *bi = bdev_get_integrity(bdev);
-
-       if (bi == NULL)
-               return 0;
-
-       if (rw == READ && bi->verify_fn != NULL &&
-           (bi->flags & INTEGRITY_FLAG_READ))
-               return 1;
-
-       if (rw == WRITE && bi->generate_fn != NULL &&
-           (bi->flags & INTEGRITY_FLAG_WRITE))
-               return 1;
-
-       return 0;
+       return disk->integrity;
 }
 
 static inline int blk_integrity_rq(struct request *rq)
@@ -1004,7 +1041,7 @@ static inline int blk_integrity_rq(struct request *rq)
 #define blk_rq_count_integrity_sg(a)           (0)
 #define blk_rq_map_integrity_sg(a, b)          (0)
 #define bdev_get_integrity(a)                  (0)
-#define bdev_get_tag_size(a)                   (0)
+#define blk_get_integrity(a)                   (0)
 #define blk_integrity_compare(a, b)            (0)
 #define blk_integrity_register(a, b)           (0)
 #define blk_integrity_unregister(a)            do { } while (0);
index d084b8d227a52fb978c02a4f07d98e08b653502b..3a31eb506164a814a2b9599d11d709f9915ed1cc 100644 (file)
@@ -1,8 +1,10 @@
 #ifndef BLKTRACE_H
 #define BLKTRACE_H
 
+#ifdef __KERNEL__
 #include <linux/blkdev.h>
 #include <linux/relay.h>
+#endif
 
 /*
  * Trace categories
@@ -21,6 +23,7 @@ enum blktrace_cat {
        BLK_TC_NOTIFY   = 1 << 10,      /* special message */
        BLK_TC_AHEAD    = 1 << 11,      /* readahead */
        BLK_TC_META     = 1 << 12,      /* metadata */
+       BLK_TC_DISCARD  = 1 << 13,      /* discard requests */
 
        BLK_TC_END      = 1 << 15,      /* only 16-bits, reminder */
 };
@@ -47,6 +50,7 @@ enum blktrace_act {
        __BLK_TA_SPLIT,                 /* bio was split */
        __BLK_TA_BOUNCE,                /* bio was bounced */
        __BLK_TA_REMAP,                 /* bio was remapped */
+       __BLK_TA_ABORT,                 /* request aborted */
 };
 
 /*
@@ -77,6 +81,7 @@ enum blktrace_notify {
 #define BLK_TA_SPLIT           (__BLK_TA_SPLIT)
 #define BLK_TA_BOUNCE          (__BLK_TA_BOUNCE)
 #define BLK_TA_REMAP           (__BLK_TA_REMAP | BLK_TC_ACT(BLK_TC_QUEUE))
+#define BLK_TA_ABORT           (__BLK_TA_ABORT | BLK_TC_ACT(BLK_TC_QUEUE))
 
 #define BLK_TN_PROCESS         (__BLK_TN_PROCESS | BLK_TC_ACT(BLK_TC_NOTIFY))
 #define BLK_TN_TIMESTAMP       (__BLK_TN_TIMESTAMP | BLK_TC_ACT(BLK_TC_NOTIFY))
@@ -89,17 +94,17 @@ enum blktrace_notify {
  * The trace itself
  */
 struct blk_io_trace {
-       u32 magic;              /* MAGIC << 8 | version */
-       u32 sequence;           /* event number */
-       u64 time;               /* in microseconds */
-       u64 sector;             /* disk offset */
-       u32 bytes;              /* transfer length */
-       u32 action;             /* what happened */
-       u32 pid;                /* who did it */
-       u32 device;             /* device number */
-       u32 cpu;                /* on what cpu did it happen */
-       u16 error;              /* completion error */
-       u16 pdu_len;            /* length of data after this trace */
+       __u32 magic;            /* MAGIC << 8 | version */
+       __u32 sequence;         /* event number */
+       __u64 time;             /* in microseconds */
+       __u64 sector;           /* disk offset */
+       __u32 bytes;            /* transfer length */
+       __u32 action;           /* what happened */
+       __u32 pid;              /* who did it */
+       __u32 device;           /* device number */
+       __u32 cpu;              /* on what cpu did it happen */
+       __u16 error;            /* completion error */
+       __u16 pdu_len;          /* length of data after this trace */
 };
 
 /*
@@ -117,6 +122,23 @@ enum {
        Blktrace_stopped,
 };
 
+#define BLKTRACE_BDEV_SIZE     32
+
+/*
+ * User setup structure passed with BLKTRACESTART
+ */
+struct blk_user_trace_setup {
+       char name[BLKTRACE_BDEV_SIZE];  /* output */
+       __u16 act_mask;                 /* input */
+       __u32 buf_size;                 /* input */
+       __u32 buf_nr;                   /* input */
+       __u64 start_lba;
+       __u64 end_lba;
+       __u32 pid;
+};
+
+#ifdef __KERNEL__
+#if defined(CONFIG_BLK_DEV_IO_TRACE)
 struct blk_trace {
        int trace_state;
        struct rchan *rchan;
@@ -133,21 +155,6 @@ struct blk_trace {
        atomic_t dropped;
 };
 
-/*
- * User setup structure passed with BLKTRACESTART
- */
-struct blk_user_trace_setup {
-       char name[BDEVNAME_SIZE];       /* output */
-       u16 act_mask;                   /* input */
-       u32 buf_size;                   /* input */
-       u32 buf_nr;                     /* input */
-       u64 start_lba;
-       u64 end_lba;
-       u32 pid;
-};
-
-#ifdef __KERNEL__
-#if defined(CONFIG_BLK_DEV_IO_TRACE)
 extern int blk_trace_ioctl(struct block_device *, unsigned, char __user *);
 extern void blk_trace_shutdown(struct request_queue *);
 extern void __blk_add_trace(struct blk_trace *, sector_t, int, int, u32, int, int, void *);
@@ -195,6 +202,9 @@ static inline void blk_add_trace_rq(struct request_queue *q, struct request *rq,
        if (likely(!bt))
                return;
 
+       if (blk_discard_rq(rq))
+               rw |= (1 << BIO_RW_DISCARD);
+
        if (blk_pc_request(rq)) {
                what |= BLK_TC_ACT(BLK_TC_PC);
                __blk_add_trace(bt, 0, rq->data_len, rw, what, rq->errors, sizeof(rq->cmd), rq->cmd);
index 02ef8835999cf666c88bb587e47ff7104c0275ac..4a6b604ef7e4ae323d9f71fe2569ef5ed318b70c 100644 (file)
 
 #include <linux/wait.h>
 
+/**
+ * struct completion - structure used to maintain state for a "completion"
+ *
+ * This is the opaque structure used to maintain the state for a "completion".
+ * Completions currently use a FIFO to queue threads that have to wait for
+ * the "completion" event.
+ *
+ * See also:  complete(), wait_for_completion() (and friends _timeout,
+ * _interruptible, _interruptible_timeout, and _killable), init_completion(),
+ * and macros DECLARE_COMPLETION(), DECLARE_COMPLETION_ONSTACK(), and
+ * INIT_COMPLETION().
+ */
 struct completion {
        unsigned int done;
        wait_queue_head_t wait;
@@ -21,6 +33,14 @@ struct completion {
 #define COMPLETION_INITIALIZER_ONSTACK(work) \
        ({ init_completion(&work); work; })
 
+/**
+ * DECLARE_COMPLETION: - declare and initialize a completion structure
+ * @work:  identifier for the completion structure
+ *
+ * This macro declares and initializes a completion structure. Generally used
+ * for static declarations. You should use the _ONSTACK variant for automatic
+ * variables.
+ */
 #define DECLARE_COMPLETION(work) \
        struct completion work = COMPLETION_INITIALIZER(work)
 
@@ -29,6 +49,13 @@ struct completion {
  * completions - so we use the _ONSTACK() variant for those that
  * are on the kernel stack:
  */
+/**
+ * DECLARE_COMPLETION_ONSTACK: - declare and initialize a completion structure
+ * @work:  identifier for the completion structure
+ *
+ * This macro declares and initializes a completion structure on the kernel
+ * stack.
+ */
 #ifdef CONFIG_LOCKDEP
 # define DECLARE_COMPLETION_ONSTACK(work) \
        struct completion work = COMPLETION_INITIALIZER_ONSTACK(work)
@@ -36,6 +63,13 @@ struct completion {
 # define DECLARE_COMPLETION_ONSTACK(work) DECLARE_COMPLETION(work)
 #endif
 
+/**
+ * init_completion: - Initialize a dynamically allocated completion
+ * @x:  completion structure that is to be initialized
+ *
+ * This inline function will initialize a dynamically created completion
+ * structure.
+ */
 static inline void init_completion(struct completion *x)
 {
        x->done = 0;
@@ -55,6 +89,13 @@ extern bool completion_done(struct completion *x);
 extern void complete(struct completion *);
 extern void complete_all(struct completion *);
 
+/**
+ * INIT_COMPLETION: - reinitialize a completion structure
+ * @x:  completion structure to be reinitialized
+ *
+ * This macro should be used to reinitialize a completion structure so it can
+ * be reused. This is especially important after complete_all() is used.
+ */
 #define INIT_COMPLETION(x)     ((x).done = 0)
 
 
index d7faf88084973c6a5bfbfca9fe717352b2e1e1a2..c2747ac2ae43b8a7b22bebdef63ee92cbcf1c31a 100644 (file)
@@ -69,6 +69,7 @@ static inline void unregister_cpu_notifier(struct notifier_block *nb)
 #endif
 
 int cpu_up(unsigned int cpu);
+void notify_cpu_starting(unsigned int cpu);
 extern void cpu_hotplug_init(void);
 extern void cpu_maps_update_begin(void);
 extern void cpu_maps_update_done(void);
index c43dc47fdf75e8127498a79290c6c10ef4b945e8..3d2317e4af2e4b4475c2fc18ff1db3b475ae1d52 100644 (file)
@@ -38,6 +38,7 @@
 #define CRYPTO_ALG_TYPE_DIGEST         0x00000008
 #define CRYPTO_ALG_TYPE_HASH           0x00000009
 #define CRYPTO_ALG_TYPE_AHASH          0x0000000a
+#define CRYPTO_ALG_TYPE_RNG            0x0000000c
 
 #define CRYPTO_ALG_TYPE_HASH_MASK      0x0000000e
 #define CRYPTO_ALG_TYPE_AHASH_MASK     0x0000000c
  */
 #define CRYPTO_ALG_GENIV               0x00000200
 
+/*
+ * Set if the algorithm has passed automated run-time testing.  Note that
+ * if there is no run-time testing for a given algorithm it is considered
+ * to have passed.
+ */
+
+#define CRYPTO_ALG_TESTED              0x00000400
+
 /*
  * Transform masks and values (for crt_flags).
  */
@@ -105,6 +114,7 @@ struct crypto_aead;
 struct crypto_blkcipher;
 struct crypto_hash;
 struct crypto_ahash;
+struct crypto_rng;
 struct crypto_tfm;
 struct crypto_type;
 struct aead_givcrypt_request;
@@ -290,6 +300,15 @@ struct compress_alg {
                              unsigned int slen, u8 *dst, unsigned int *dlen);
 };
 
+struct rng_alg {
+       int (*rng_make_random)(struct crypto_rng *tfm, u8 *rdata,
+                              unsigned int dlen);
+       int (*rng_reset)(struct crypto_rng *tfm, u8 *seed, unsigned int slen);
+
+       unsigned int seedsize;
+};
+
+
 #define cra_ablkcipher cra_u.ablkcipher
 #define cra_aead       cra_u.aead
 #define cra_blkcipher  cra_u.blkcipher
@@ -298,6 +317,7 @@ struct compress_alg {
 #define cra_hash       cra_u.hash
 #define cra_ahash      cra_u.ahash
 #define cra_compress   cra_u.compress
+#define cra_rng                cra_u.rng
 
 struct crypto_alg {
        struct list_head cra_list;
@@ -325,6 +345,7 @@ struct crypto_alg {
                struct hash_alg hash;
                struct ahash_alg ahash;
                struct compress_alg compress;
+               struct rng_alg rng;
        } cra_u;
 
        int (*cra_init)(struct crypto_tfm *tfm);
@@ -430,6 +451,12 @@ struct compress_tfm {
                              u8 *dst, unsigned int *dlen);
 };
 
+struct rng_tfm {
+       int (*rng_gen_random)(struct crypto_rng *tfm, u8 *rdata,
+                             unsigned int dlen);
+       int (*rng_reset)(struct crypto_rng *tfm, u8 *seed, unsigned int slen);
+};
+
 #define crt_ablkcipher crt_u.ablkcipher
 #define crt_aead       crt_u.aead
 #define crt_blkcipher  crt_u.blkcipher
@@ -437,6 +464,7 @@ struct compress_tfm {
 #define crt_hash       crt_u.hash
 #define crt_ahash      crt_u.ahash
 #define crt_compress   crt_u.compress
+#define crt_rng                crt_u.rng
 
 struct crypto_tfm {
 
@@ -450,6 +478,7 @@ struct crypto_tfm {
                struct hash_tfm hash;
                struct ahash_tfm ahash;
                struct compress_tfm compress;
+               struct rng_tfm rng;
        } crt_u;
        
        struct crypto_alg *__crt_alg;
@@ -481,6 +510,10 @@ struct crypto_hash {
        struct crypto_tfm base;
 };
 
+struct crypto_rng {
+       struct crypto_tfm base;
+};
+
 enum {
        CRYPTOA_UNSPEC,
        CRYPTOA_ALG,
@@ -515,6 +548,8 @@ struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags);
 struct crypto_tfm *crypto_alloc_base(const char *alg_name, u32 type, u32 mask);
 void crypto_free_tfm(struct crypto_tfm *tfm);
 
+int alg_test(const char *driver, const char *alg, u32 type, u32 mask);
+
 /*
  * Transform helpers which query the underlying algorithm.
  */
index a90222e3297d807e554ca270b50f097a3a5dfbc7..08d783592b73ef4ef6bf8f2b03c8b1359ebe5b40 100644 (file)
@@ -13,7 +13,6 @@
 
 struct dm_target;
 struct dm_table;
-struct dm_dev;
 struct mapped_device;
 struct bio_vec;
 
@@ -84,6 +83,12 @@ void dm_error(const char *message);
  */
 void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev);
 
+struct dm_dev {
+       struct block_device *bdev;
+       int mode;
+       char name[16];
+};
+
 /*
  * Constructors should call these functions to ensure destination devices
  * are opened/closed correctly.
@@ -202,6 +207,7 @@ int dm_copy_name_and_uuid(struct mapped_device *md, char *name, char *uuid);
 struct gendisk *dm_disk(struct mapped_device *md);
 int dm_suspended(struct mapped_device *md);
 int dm_noflush_suspending(struct dm_target *ti);
+union map_info *dm_get_mapinfo(struct bio *bio);
 
 /*
  * Geometry functions.
@@ -231,6 +237,11 @@ int dm_table_add_target(struct dm_table *t, const char *type,
  */
 int dm_table_complete(struct dm_table *t);
 
+/*
+ * Unplug all devices in a table.
+ */
+void dm_table_unplug_all(struct dm_table *t);
+
 /*
  * Table reference counting.
  */
@@ -256,6 +267,11 @@ void dm_table_event(struct dm_table *t);
  */
 int dm_swap_table(struct mapped_device *md, struct dm_table *t);
 
+/*
+ * A wrapper around vmalloc.
+ */
+void *dm_vcalloc(unsigned long nmemb, unsigned long elem_size);
+
 /*-----------------------------------------------------------------
  * Macros.
  *---------------------------------------------------------------*/
index 4d8372d135df8df6d4f648b009faaa5d4d315538..246937c9cbc780db2cc30b542453d401bcd6c334 100644 (file)
@@ -199,6 +199,11 @@ struct class {
        struct class_private *p;
 };
 
+struct class_dev_iter {
+       struct klist_iter               ki;
+       const struct device_type        *type;
+};
+
 extern struct kobject *sysfs_dev_block_kobj;
 extern struct kobject *sysfs_dev_char_kobj;
 extern int __must_check __class_register(struct class *class,
@@ -213,6 +218,13 @@ extern void class_unregister(struct class *class);
        __class_register(class, &__key);        \
 })
 
+extern void class_dev_iter_init(struct class_dev_iter *iter,
+                               struct class *class,
+                               struct device *start,
+                               const struct device_type *type);
+extern struct device *class_dev_iter_next(struct class_dev_iter *iter);
+extern void class_dev_iter_exit(struct class_dev_iter *iter);
+
 extern int class_for_each_device(struct class *class, struct device *start,
                                 void *data,
                                 int (*fn)(struct device *dev, void *data));
@@ -396,7 +408,7 @@ struct device {
        spinlock_t              devres_lock;
        struct list_head        devres_head;
 
-       struct list_head        node;
+       struct klist_node       knode_class;
        struct class            *class;
        dev_t                   devt;   /* dev_t, creates the sysfs "dev" */
        struct attribute_group  **groups;       /* optional groups */
index 203a025e30e5a88251d909b263a9b0046dc18d2a..b9cd38603fd8325bf21c21206ab7fe246d026c6c 100644 (file)
@@ -2,7 +2,7 @@
 *******************************************************************************
 **
 **  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
-**  Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2004-2008 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -65,9 +65,12 @@ struct dlm_lksb {
        char *   sb_lvbptr;
 };
 
+/* dlm_new_lockspace() flags */
+
 #define DLM_LSFL_NODIR         0x00000001
 #define DLM_LSFL_TIMEWARN      0x00000002
 #define DLM_LSFL_FS            0x00000004
+#define DLM_LSFL_NEWEXCL       0x00000008
 
 #ifdef __KERNEL__
 
index c6034508fed9a3c1e795f27a8ef188e6452db834..3060783c419154bace8dd6eaffbee3d3d022e060 100644 (file)
@@ -26,7 +26,7 @@
 /* Version of the device interface */
 #define DLM_DEVICE_VERSION_MAJOR 6
 #define DLM_DEVICE_VERSION_MINOR 0
-#define DLM_DEVICE_VERSION_PATCH 0
+#define DLM_DEVICE_VERSION_PATCH 1
 
 /* struct passed to the lock write */
 struct dlm_lock_params {
index 639624b55fbe34914f7bd7eb7d80d3deab756cb4..92f6f634e3e62ce77c38d46e6ecb88bf396ceea2 100644 (file)
@@ -112,6 +112,7 @@ extern struct request *elv_latter_request(struct request_queue *, struct request
 extern int elv_register_queue(struct request_queue *q);
 extern void elv_unregister_queue(struct request_queue *q);
 extern int elv_may_queue(struct request_queue *, int);
+extern void elv_abort_queue(struct request_queue *);
 extern void elv_completed_request(struct request_queue *, struct request *);
 extern int elv_set_request(struct request_queue *, struct request *, gfp_t);
 extern void elv_put_request(struct request_queue *, struct request *);
@@ -173,15 +174,15 @@ enum {
 #define rb_entry_rq(node)      rb_entry((node), struct request, rb_node)
 
 /*
- * Hack to reuse the donelist list_head as the fifo time holder while
+ * Hack to reuse the csd.list list_head as the fifo time holder while
  * the request is in the io scheduler. Saves an unsigned long in rq.
  */
-#define rq_fifo_time(rq)       ((unsigned long) (rq)->donelist.next)
-#define rq_set_fifo_time(rq,exp)       ((rq)->donelist.next = (void *) (exp))
+#define rq_fifo_time(rq)       ((unsigned long) (rq)->csd.list.next)
+#define rq_set_fifo_time(rq,exp)       ((rq)->csd.list.next = (void *) (exp))
 #define rq_entry_fifo(ptr)     list_entry((ptr), struct request, queuelist)
 #define rq_fifo_clear(rq)      do {            \
        list_del_init(&(rq)->queuelist);        \
-       INIT_LIST_HEAD(&(rq)->donelist);        \
+       INIT_LIST_HEAD(&(rq)->csd.list);        \
        } while (0)
 
 /*
index b6bd41d2b4606ba8d2e4b73ccd1e4ad52df8f036..f5d194af07a878b093501bbada51bc51a1ca0710 100644 (file)
@@ -15,10 +15,16 @@ struct floppy_struct {
                        sect,           /* sectors per track */
                        head,           /* nr of heads */
                        track,          /* nr of tracks */
-                       stretch;        /* !=0 means double track steps */
+                       stretch;        /* bit 0 !=0 means double track steps */
+                                       /* bit 1 != 0 means swap sides */
+                                       /* bits 2..9 give the first sector */
+                                       /*  number (the LSB is flipped) */
 #define FD_STRETCH 1
 #define FD_SWAPSIDES 2
 #define FD_ZEROBASED 4
+#define FD_SECTBASEMASK 0x3FC
+#define FD_MKSECTBASE(s) (((s) ^ 1) << 2)
+#define FD_SECTBASE(floppy) ((((floppy)->stretch & FD_SECTBASEMASK) >> 2) ^ 1)
 
        unsigned char   gap,            /* gap1 size */
 
index 580b513668feffbb32f9d161113e10b17718dfe5..32477e8872d544ce9abeca8cde1b603d4739814d 100644 (file)
@@ -86,7 +86,9 @@ extern int dir_notify_enable;
 #define READ_META      (READ | (1 << BIO_RW_META))
 #define WRITE_SYNC     (WRITE | (1 << BIO_RW_SYNC))
 #define SWRITE_SYNC    (SWRITE | (1 << BIO_RW_SYNC))
-#define WRITE_BARRIER  ((1 << BIO_RW) | (1 << BIO_RW_BARRIER))
+#define WRITE_BARRIER  (WRITE | (1 << BIO_RW_BARRIER))
+#define DISCARD_NOBARRIER (1 << BIO_RW_DISCARD)
+#define DISCARD_BARRIER ((1 << BIO_RW_DISCARD) | (1 << BIO_RW_BARRIER))
 
 #define SEL_IN         1
 #define SEL_OUT                2
@@ -222,6 +224,7 @@ extern int dir_notify_enable;
 #define BLKTRACESTART _IO(0x12,116)
 #define BLKTRACESTOP _IO(0x12,117)
 #define BLKTRACETEARDOWN _IO(0x12,118)
+#define BLKDISCARD _IO(0x12,119)
 
 #define BMAP_IOCTL 1           /* obsolete - kept for compatibility */
 #define FIBMAP    _IO(0x00,1)  /* bmap access */
@@ -1682,6 +1685,7 @@ extern void chrdev_show(struct seq_file *,off_t);
 
 /* fs/block_dev.c */
 #define BDEVNAME_SIZE  32      /* Largest string for a blockdev identifier */
+#define BDEVT_SIZE     10      /* Largest string for MAJ:MIN for blkdev */
 
 #ifdef CONFIG_BLOCK
 #define BLKDEV_MAJOR_HASH_SIZE 255
@@ -1718,6 +1722,9 @@ extern int fs_may_remount_ro(struct super_block *);
  */
 #define bio_data_dir(bio)      ((bio)->bi_rw & 1)
 
+extern void check_disk_size_change(struct gendisk *disk,
+                                  struct block_device *bdev);
+extern int revalidate_disk(struct gendisk *);
 extern int check_disk_change(struct block_device *);
 extern int __invalidate_device(struct block_device *);
 extern int invalidate_partition(struct gendisk *, int);
index be4f5e5bfe06ccd2a5a65917b2bc6d09cfd8630c..206cdf96c3a751fb926750fcd29c5cf828464392 100644 (file)
 
 #include <linux/types.h>
 #include <linux/kdev_t.h>
+#include <linux/rcupdate.h>
 
 #ifdef CONFIG_BLOCK
 
-#define kobj_to_dev(k) container_of(k, struct device, kobj)
-#define dev_to_disk(device) container_of(device, struct gendisk, dev)
-#define dev_to_part(device) container_of(device, struct hd_struct, dev)
+#define kobj_to_dev(k)         container_of((k), struct device, kobj)
+#define dev_to_disk(device)    container_of((device), struct gendisk, part0.__dev)
+#define dev_to_part(device)    container_of((device), struct hd_struct, __dev)
+#define disk_to_dev(disk)      (&(disk)->part0.__dev)
+#define part_to_dev(part)      (&((part)->__dev))
 
 extern struct device_type part_type;
 extern struct kobject *block_depr;
@@ -55,6 +58,9 @@ enum {
        UNIXWARE_PARTITION = 0x63,      /* Same as GNU_HURD and SCO Unix */
 };
 
+#define DISK_MAX_PARTS                 256
+#define DISK_NAME_LEN                  32
+
 #include <linux/major.h>
 #include <linux/device.h>
 #include <linux/smp.h>
@@ -87,7 +93,7 @@ struct disk_stats {
 struct hd_struct {
        sector_t start_sect;
        sector_t nr_sects;
-       struct device dev;
+       struct device __dev;
        struct kobject *holder_dir;
        int policy, partno;
 #ifdef CONFIG_FAIL_MAKE_REQUEST
@@ -100,6 +106,7 @@ struct hd_struct {
 #else
        struct disk_stats dkstats;
 #endif
+       struct rcu_head rcu_head;
 };
 
 #define GENHD_FL_REMOVABLE                     1
@@ -108,100 +115,148 @@ struct hd_struct {
 #define GENHD_FL_CD                            8
 #define GENHD_FL_UP                            16
 #define GENHD_FL_SUPPRESS_PARTITION_INFO       32
-#define GENHD_FL_FAIL                          64
+#define GENHD_FL_EXT_DEVT                      64 /* allow extended devt */
+
+#define BLK_SCSI_MAX_CMDS      (256)
+#define BLK_SCSI_CMD_PER_LONG  (BLK_SCSI_MAX_CMDS / (sizeof(long) * 8))
+
+struct blk_scsi_cmd_filter {
+       unsigned long read_ok[BLK_SCSI_CMD_PER_LONG];
+       unsigned long write_ok[BLK_SCSI_CMD_PER_LONG];
+       struct kobject kobj;
+};
+
+struct disk_part_tbl {
+       struct rcu_head rcu_head;
+       int len;
+       struct hd_struct *part[];
+};
 
 struct gendisk {
+       /* major, first_minor and minors are input parameters only,
+        * don't use directly.  Use disk_devt() and disk_max_parts().
+        */
        int major;                      /* major number of driver */
        int first_minor;
        int minors;                     /* maximum number of minors, =1 for
                                          * disks that can't be partitioned. */
-       char disk_name[32];             /* name of major driver */
-       struct hd_struct **part;        /* [indexed by minor] */
+
+       char disk_name[DISK_NAME_LEN];  /* name of major driver */
+
+       /* Array of pointers to partitions indexed by partno.
+        * Protected with matching bdev lock but stat and other
+        * non-critical accesses use RCU.  Always access through
+        * helpers.
+        */
+       struct disk_part_tbl *part_tbl;
+       struct hd_struct part0;
+
        struct block_device_operations *fops;
        struct request_queue *queue;
        void *private_data;
-       sector_t capacity;
 
        int flags;
        struct device *driverfs_dev;  // FIXME: remove
-       struct device dev;
-       struct kobject *holder_dir;
        struct kobject *slave_dir;
 
        struct timer_rand_state *random;
-       int policy;
 
        atomic_t sync_io;               /* RAID */
-       unsigned long stamp;
-       int in_flight;
-#ifdef CONFIG_SMP
-       struct disk_stats *dkstats;
-#else
-       struct disk_stats dkstats;
-#endif
        struct work_struct async_notify;
 #ifdef  CONFIG_BLK_DEV_INTEGRITY
        struct blk_integrity *integrity;
 #endif
+       int node_id;
 };
 
-/* 
- * Macros to operate on percpu disk statistics:
- *
- * The __ variants should only be called in critical sections. The full
- * variants disable/enable preemption.
- */
-static inline struct hd_struct *get_part(struct gendisk *gendiskp,
-                                        sector_t sector)
+static inline struct gendisk *part_to_disk(struct hd_struct *part)
 {
-       struct hd_struct *part;
-       int i;
-       for (i = 0; i < gendiskp->minors - 1; i++) {
-               part = gendiskp->part[i];
-               if (part && part->start_sect <= sector
-                   && sector < part->start_sect + part->nr_sects)
-                       return part;
+       if (likely(part)) {
+               if (part->partno)
+                       return dev_to_disk(part_to_dev(part)->parent);
+               else
+                       return dev_to_disk(part_to_dev(part));
        }
        return NULL;
 }
 
-#ifdef CONFIG_SMP
-#define __disk_stat_add(gendiskp, field, addnd)        \
-       (per_cpu_ptr(gendiskp->dkstats, smp_processor_id())->field += addnd)
+static inline int disk_max_parts(struct gendisk *disk)
+{
+       if (disk->flags & GENHD_FL_EXT_DEVT)
+               return DISK_MAX_PARTS;
+       return disk->minors;
+}
 
-#define disk_stat_read(gendiskp, field)                                        \
-({                                                                     \
-       typeof(gendiskp->dkstats->field) res = 0;                       \
-       int i;                                                          \
-       for_each_possible_cpu(i)                                        \
-               res += per_cpu_ptr(gendiskp->dkstats, i)->field;        \
-       res;                                                            \
-})
+static inline bool disk_partitionable(struct gendisk *disk)
+{
+       return disk_max_parts(disk) > 1;
+}
 
-static inline void disk_stat_set_all(struct gendisk *gendiskp, int value)      {
-       int i;
+static inline dev_t disk_devt(struct gendisk *disk)
+{
+       return disk_to_dev(disk)->devt;
+}
 
-       for_each_possible_cpu(i)
-               memset(per_cpu_ptr(gendiskp->dkstats, i), value,
-                               sizeof(struct disk_stats));
-}              
+static inline dev_t part_devt(struct hd_struct *part)
+{
+       return part_to_dev(part)->devt;
+}
 
-#define __part_stat_add(part, field, addnd)                            \
-       (per_cpu_ptr(part->dkstats, smp_processor_id())->field += addnd)
+extern struct hd_struct *disk_get_part(struct gendisk *disk, int partno);
 
-#define __all_stat_add(gendiskp, part, field, addnd, sector)   \
-({                                                             \
-       if (part)                                               \
-               __part_stat_add(part, field, addnd);            \
-       __disk_stat_add(gendiskp, field, addnd);                \
-})
+static inline void disk_put_part(struct hd_struct *part)
+{
+       if (likely(part))
+               put_device(part_to_dev(part));
+}
+
+/*
+ * Smarter partition iterator without context limits.
+ */
+#define DISK_PITER_REVERSE     (1 << 0) /* iterate in the reverse direction */
+#define DISK_PITER_INCL_EMPTY  (1 << 1) /* include 0-sized parts */
+#define DISK_PITER_INCL_PART0  (1 << 2) /* include partition 0 */
+
+struct disk_part_iter {
+       struct gendisk          *disk;
+       struct hd_struct        *part;
+       int                     idx;
+       unsigned int            flags;
+};
+
+extern void disk_part_iter_init(struct disk_part_iter *piter,
+                                struct gendisk *disk, unsigned int flags);
+extern struct hd_struct *disk_part_iter_next(struct disk_part_iter *piter);
+extern void disk_part_iter_exit(struct disk_part_iter *piter);
+
+extern struct hd_struct *disk_map_sector_rcu(struct gendisk *disk,
+                                            sector_t sector);
+
+/*
+ * Macros to operate on percpu disk statistics:
+ *
+ * {disk|part|all}_stat_{add|sub|inc|dec}() modify the stat counters
+ * and should be called between disk_stat_lock() and
+ * disk_stat_unlock().
+ *
+ * part_stat_read() can be called at any time.
+ *
+ * part_stat_{add|set_all}() and {init|free}_part_stats are for
+ * internal use only.
+ */
+#ifdef CONFIG_SMP
+#define part_stat_lock()       ({ rcu_read_lock(); get_cpu(); })
+#define part_stat_unlock()     do { put_cpu(); rcu_read_unlock(); } while (0)
+
+#define __part_stat_add(cpu, part, field, addnd)                       \
+       (per_cpu_ptr((part)->dkstats, (cpu))->field += (addnd))
 
 #define part_stat_read(part, field)                                    \
 ({                                                                     \
-       typeof(part->dkstats->field) res = 0;                           \
+       typeof((part)->dkstats->field) res = 0;                         \
        int i;                                                          \
        for_each_possible_cpu(i)                                        \
-               res += per_cpu_ptr(part->dkstats, i)->field;            \
+               res += per_cpu_ptr((part)->dkstats, i)->field;          \
        res;                                                            \
 })
 
@@ -213,171 +268,107 @@ static inline void part_stat_set_all(struct hd_struct *part, int value)
                memset(per_cpu_ptr(part->dkstats, i), value,
                                sizeof(struct disk_stats));
 }
-                               
-#else /* !CONFIG_SMP */
-#define __disk_stat_add(gendiskp, field, addnd) \
-                               (gendiskp->dkstats.field += addnd)
-#define disk_stat_read(gendiskp, field)        (gendiskp->dkstats.field)
 
-static inline void disk_stat_set_all(struct gendisk *gendiskp, int value)
+static inline int init_part_stats(struct hd_struct *part)
 {
-       memset(&gendiskp->dkstats, value, sizeof (struct disk_stats));
+       part->dkstats = alloc_percpu(struct disk_stats);
+       if (!part->dkstats)
+               return 0;
+       return 1;
 }
 
-#define __part_stat_add(part, field, addnd) \
-       (part->dkstats.field += addnd)
-
-#define __all_stat_add(gendiskp, part, field, addnd, sector)   \
-({                                                             \
-       if (part)                                               \
-               part->dkstats.field += addnd;                   \
-       __disk_stat_add(gendiskp, field, addnd);                \
-})
-
-#define part_stat_read(part, field)    (part->dkstats.field)
-
-static inline void part_stat_set_all(struct hd_struct *part, int value)
+static inline void free_part_stats(struct hd_struct *part)
 {
-       memset(&part->dkstats, value, sizeof(struct disk_stats));
+       free_percpu(part->dkstats);
 }
 
-#endif /* CONFIG_SMP */
+#else /* !CONFIG_SMP */
+#define part_stat_lock()       ({ rcu_read_lock(); 0; })
+#define part_stat_unlock()     rcu_read_unlock()
 
-#define disk_stat_add(gendiskp, field, addnd)                  \
-       do {                                                    \
-               preempt_disable();                              \
-               __disk_stat_add(gendiskp, field, addnd);        \
-               preempt_enable();                               \
-       } while (0)
-
-#define __disk_stat_dec(gendiskp, field) __disk_stat_add(gendiskp, field, -1)
-#define disk_stat_dec(gendiskp, field) disk_stat_add(gendiskp, field, -1)
-
-#define __disk_stat_inc(gendiskp, field) __disk_stat_add(gendiskp, field, 1)
-#define disk_stat_inc(gendiskp, field) disk_stat_add(gendiskp, field, 1)
-
-#define __disk_stat_sub(gendiskp, field, subnd) \
-               __disk_stat_add(gendiskp, field, -subnd)
-#define disk_stat_sub(gendiskp, field, subnd) \
-               disk_stat_add(gendiskp, field, -subnd)
-
-#define part_stat_add(gendiskp, field, addnd)          \
-       do {                                            \
-               preempt_disable();                      \
-               __part_stat_add(gendiskp, field, addnd);\
-               preempt_enable();                       \
-       } while (0)
-
-#define __part_stat_dec(gendiskp, field) __part_stat_add(gendiskp, field, -1)
-#define part_stat_dec(gendiskp, field) part_stat_add(gendiskp, field, -1)
-
-#define __part_stat_inc(gendiskp, field) __part_stat_add(gendiskp, field, 1)
-#define part_stat_inc(gendiskp, field) part_stat_add(gendiskp, field, 1)
-
-#define __part_stat_sub(gendiskp, field, subnd) \
-               __part_stat_add(gendiskp, field, -subnd)
-#define part_stat_sub(gendiskp, field, subnd) \
-               part_stat_add(gendiskp, field, -subnd)
-
-#define all_stat_add(gendiskp, part, field, addnd, sector)     \
-       do {                                                    \
-               preempt_disable();                              \
-               __all_stat_add(gendiskp, part, field, addnd, sector);   \
-               preempt_enable();                               \
-       } while (0)
-
-#define __all_stat_dec(gendiskp, field, sector) \
-               __all_stat_add(gendiskp, field, -1, sector)
-#define all_stat_dec(gendiskp, field, sector) \
-               all_stat_add(gendiskp, field, -1, sector)
-
-#define __all_stat_inc(gendiskp, part, field, sector) \
-               __all_stat_add(gendiskp, part, field, 1, sector)
-#define all_stat_inc(gendiskp, part, field, sector) \
-               all_stat_add(gendiskp, part, field, 1, sector)
-
-#define __all_stat_sub(gendiskp, part, field, subnd, sector) \
-               __all_stat_add(gendiskp, part, field, -subnd, sector)
-#define all_stat_sub(gendiskp, part, field, subnd, sector) \
-               all_stat_add(gendiskp, part, field, -subnd, sector)
-
-/* Inlines to alloc and free disk stats in struct gendisk */
-#ifdef  CONFIG_SMP
-static inline int init_disk_stats(struct gendisk *disk)
-{
-       disk->dkstats = alloc_percpu(struct disk_stats);
-       if (!disk->dkstats)
-               return 0;
-       return 1;
-}
+#define __part_stat_add(cpu, part, field, addnd)                               \
+       ((part)->dkstats.field += addnd)
+
+#define part_stat_read(part, field)    ((part)->dkstats.field)
 
-static inline void free_disk_stats(struct gendisk *disk)
+static inline void part_stat_set_all(struct hd_struct *part, int value)
 {
-       free_percpu(disk->dkstats);
+       memset(&part->dkstats, value, sizeof(struct disk_stats));
 }
 
 static inline int init_part_stats(struct hd_struct *part)
 {
-       part->dkstats = alloc_percpu(struct disk_stats);
-       if (!part->dkstats)
-               return 0;
        return 1;
 }
 
 static inline void free_part_stats(struct hd_struct *part)
 {
-       free_percpu(part->dkstats);
-}
-
-#else  /* CONFIG_SMP */
-static inline int init_disk_stats(struct gendisk *disk)
-{
-       return 1;
 }
 
-static inline void free_disk_stats(struct gendisk *disk)
-{
-}
+#endif /* CONFIG_SMP */
 
-static inline int init_part_stats(struct hd_struct *part)
+#define part_stat_add(cpu, part, field, addnd) do {                    \
+       __part_stat_add((cpu), (part), field, addnd);                   \
+       if ((part)->partno)                                             \
+               __part_stat_add((cpu), &part_to_disk((part))->part0,    \
+                               field, addnd);                          \
+} while (0)
+
+#define part_stat_dec(cpu, gendiskp, field)                            \
+       part_stat_add(cpu, gendiskp, field, -1)
+#define part_stat_inc(cpu, gendiskp, field)                            \
+       part_stat_add(cpu, gendiskp, field, 1)
+#define part_stat_sub(cpu, gendiskp, field, subnd)                     \
+       part_stat_add(cpu, gendiskp, field, -subnd)
+
+static inline void part_inc_in_flight(struct hd_struct *part)
 {
-       return 1;
+       part->in_flight++;
+       if (part->partno)
+               part_to_disk(part)->part0.in_flight++;
 }
 
-static inline void free_part_stats(struct hd_struct *part)
+static inline void part_dec_in_flight(struct hd_struct *part)
 {
+       part->in_flight--;
+       if (part->partno)
+               part_to_disk(part)->part0.in_flight--;
 }
-#endif /* CONFIG_SMP */
 
 /* drivers/block/ll_rw_blk.c */
-extern void disk_round_stats(struct gendisk *disk);
-extern void part_round_stats(struct hd_struct *part);
+extern void part_round_stats(int cpu, struct hd_struct *part);
 
 /* drivers/block/genhd.c */
 extern int get_blkdev_list(char *, int);
 extern void add_disk(struct gendisk *disk);
 extern void del_gendisk(struct gendisk *gp);
 extern void unlink_gendisk(struct gendisk *gp);
-extern struct gendisk *get_gendisk(dev_t dev, int *part);
+extern struct gendisk *get_gendisk(dev_t dev, int *partno);
+extern struct block_device *bdget_disk(struct gendisk *disk, int partno);
 
 extern void set_device_ro(struct block_device *bdev, int flag);
 extern void set_disk_ro(struct gendisk *disk, int flag);
 
+static inline int get_disk_ro(struct gendisk *disk)
+{
+       return disk->part0.policy;
+}
+
 /* drivers/char/random.c */
 extern void add_disk_randomness(struct gendisk *disk);
 extern void rand_initialize_disk(struct gendisk *disk);
 
 static inline sector_t get_start_sect(struct block_device *bdev)
 {
-       return bdev->bd_contains == bdev ? 0 : bdev->bd_part->start_sect;
+       return bdev->bd_part->start_sect;
 }
 static inline sector_t get_capacity(struct gendisk *disk)
 {
-       return disk->capacity;
+       return disk->part0.nr_sects;
 }
 static inline void set_capacity(struct gendisk *disk, sector_t size)
 {
-       disk->capacity = size;
+       disk->part0.nr_sects = size;
 }
 
 #ifdef CONFIG_SOLARIS_X86_PARTITION
@@ -527,9 +518,12 @@ struct unixware_disklabel {
 #define ADDPART_FLAG_RAID      1
 #define ADDPART_FLAG_WHOLEDISK 2
 
-extern dev_t blk_lookup_devt(const char *name, int part);
-extern char *disk_name (struct gendisk *hd, int part, char *buf);
+extern int blk_alloc_devt(struct hd_struct *part, dev_t *devt);
+extern void blk_free_devt(dev_t devt);
+extern dev_t blk_lookup_devt(const char *name, int partno);
+extern char *disk_name (struct gendisk *hd, int partno, char *buf);
 
+extern int disk_expand_part_tbl(struct gendisk *disk, int target);
 extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev);
 extern int __must_check add_partition(struct gendisk *, int, sector_t, sector_t, int);
 extern void delete_partition(struct gendisk *, int);
@@ -546,16 +540,23 @@ extern void blk_register_region(dev_t devt, unsigned long range,
                        void *data);
 extern void blk_unregister_region(dev_t devt, unsigned long range);
 
-static inline struct block_device *bdget_disk(struct gendisk *disk, int index)
-{
-       return bdget(MKDEV(disk->major, disk->first_minor) + index);
-}
+extern ssize_t part_size_show(struct device *dev,
+                             struct device_attribute *attr, char *buf);
+extern ssize_t part_stat_show(struct device *dev,
+                             struct device_attribute *attr, char *buf);
+#ifdef CONFIG_FAIL_MAKE_REQUEST
+extern ssize_t part_fail_show(struct device *dev,
+                             struct device_attribute *attr, char *buf);
+extern ssize_t part_fail_store(struct device *dev,
+                              struct device_attribute *attr,
+                              const char *buf, size_t count);
+#endif /* CONFIG_FAIL_MAKE_REQUEST */
 
 #else /* CONFIG_BLOCK */
 
 static inline void printk_all_partitions(void) { }
 
-static inline dev_t blk_lookup_devt(const char *name, int part)
+static inline dev_t blk_lookup_devt(const char *name, int partno)
 {
        dev_t devt = MKDEV(0, 0);
        return devt;
index c3c19f926e6f37cdcca6ab95e6ea06a5b0522462..14d0df0b5749833b823b4ff8cfd7de1c08a4e4b3 100644 (file)
@@ -118,7 +118,11 @@ struct gfs2_sb {
 
        char sb_lockproto[GFS2_LOCKNAME_LEN];
        char sb_locktable[GFS2_LOCKNAME_LEN];
-       /* In gfs1, quota and license dinodes followed */
+
+       struct gfs2_inum __pad3; /* Was quota inode in gfs1 */
+       struct gfs2_inum __pad4; /* Was licence inode in gfs1 */
+#define GFS2_HAS_UUID 1
+       __u8 sb_uuid[16]; /* The UUID, maybe 0 for backwards compat */
 };
 
 /*
index 06c338ef7f1b9ee62cc43fa4e30e9d79a3acc072..8ea98db223e567db691efb28fe1153d60d2f6d78 100644 (file)
@@ -38,7 +38,7 @@ extern void klist_init(struct klist *k, void (*get)(struct klist_node *),
                       void (*put)(struct klist_node *));
 
 struct klist_node {
-       struct klist            *n_klist;
+       void                    *n_klist;       /* never access directly */
        struct list_head        n_node;
        struct kref             n_ref;
        struct completion       n_removed;
@@ -57,7 +57,6 @@ extern int klist_node_attached(struct klist_node *n);
 
 struct klist_iter {
        struct klist            *i_klist;
-       struct list_head        *i_head;
        struct klist_node       *i_cur;
 };
 
index 225bfc5bd9ec1eb43b143d059f926918a30c2656..947cf84e555d66acc7c4869fdc6595bb1141dfcb 100644 (file)
@@ -146,6 +146,7 @@ enum {
        ATA_DFLAG_SPUNDOWN      = (1 << 14), /* XXX: for spindown_compat */
        ATA_DFLAG_SLEEPING      = (1 << 15), /* device is sleeping */
        ATA_DFLAG_DUBIOUS_XFER  = (1 << 16), /* data transfer not verified */
+       ATA_DFLAG_NO_UNLOAD     = (1 << 17), /* device doesn't support unload */
        ATA_DFLAG_INIT_MASK     = (1 << 24) - 1,
 
        ATA_DFLAG_DETACH        = (1 << 24),
@@ -244,6 +245,7 @@ enum {
        ATA_TMOUT_BOOT          = 30000,        /* heuristic */
        ATA_TMOUT_BOOT_QUICK    =  7000,        /* heuristic */
        ATA_TMOUT_INTERNAL_QUICK = 5000,
+       ATA_TMOUT_MAX_PARK      = 30000,
 
        /* FIXME: GoVault needs 2s but we can't afford that without
         * parallel probing.  800ms is enough for iVDR disk
@@ -319,8 +321,11 @@ enum {
        ATA_EH_RESET            = ATA_EH_SOFTRESET | ATA_EH_HARDRESET,
        ATA_EH_ENABLE_LINK      = (1 << 3),
        ATA_EH_LPM              = (1 << 4),  /* link power management action */
+       ATA_EH_PARK             = (1 << 5), /* unload heads and stop I/O */
 
-       ATA_EH_PERDEV_MASK      = ATA_EH_REVALIDATE,
+       ATA_EH_PERDEV_MASK      = ATA_EH_REVALIDATE | ATA_EH_PARK,
+       ATA_EH_ALL_ACTIONS      = ATA_EH_REVALIDATE | ATA_EH_RESET |
+                                 ATA_EH_ENABLE_LINK | ATA_EH_LPM,
 
        /* ata_eh_info->flags */
        ATA_EHI_HOTPLUGGED      = (1 << 0),  /* could have been hotplugged */
@@ -452,6 +457,7 @@ enum link_pm {
        MEDIUM_POWER,
 };
 extern struct device_attribute dev_attr_link_power_management_policy;
+extern struct device_attribute dev_attr_unload_heads;
 extern struct device_attribute dev_attr_em_message_type;
 extern struct device_attribute dev_attr_em_message;
 extern struct device_attribute dev_attr_sw_activity;
@@ -554,8 +560,8 @@ struct ata_ering {
 struct ata_device {
        struct ata_link         *link;
        unsigned int            devno;          /* 0 or 1 */
-       unsigned long           flags;          /* ATA_DFLAG_xxx */
        unsigned int            horkage;        /* List of broken features */
+       unsigned long           flags;          /* ATA_DFLAG_xxx */
        struct scsi_device      *sdev;          /* attached SCSI device */
 #ifdef CONFIG_ATA_ACPI
        acpi_handle             acpi_handle;
@@ -564,6 +570,7 @@ struct ata_device {
        /* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */
        u64                     n_sectors;      /* size of device, if ATA */
        unsigned int            class;          /* ATA_DEV_xxx */
+       unsigned long           unpark_deadline;
 
        u8                      pio_mode;
        u8                      dma_mode;
@@ -621,6 +628,7 @@ struct ata_eh_context {
                                               [ATA_EH_CMD_TIMEOUT_TABLE_SIZE];
        unsigned int            classes[ATA_MAX_DEVICES];
        unsigned int            did_probe_mask;
+       unsigned int            unloaded_mask;
        unsigned int            saved_ncq_enabled;
        u8                      saved_xfer_mode[ATA_MAX_DEVICES];
        /* timestamp for the last reset attempt or success */
@@ -688,7 +696,8 @@ struct ata_port {
        unsigned int            qc_active;
        int                     nr_active_links; /* #links with active qcs */
 
-       struct ata_link         link;   /* host default link */
+       struct ata_link         link;           /* host default link */
+       struct ata_link         *slave_link;    /* see ata_slave_link_init() */
 
        int                     nr_pmp_links;   /* nr of available PMP links */
        struct ata_link         *pmp_link;      /* array of PMP links */
@@ -709,6 +718,7 @@ struct ata_port {
        struct list_head        eh_done_q;
        wait_queue_head_t       eh_wait_q;
        int                     eh_tries;
+       struct completion       park_req_pending;
 
        pm_message_t            pm_mesg;
        int                     *pm_result;
@@ -772,8 +782,8 @@ struct ata_port_operations {
        /*
         * Optional features
         */
-       int  (*scr_read)(struct ata_port *ap, unsigned int sc_reg, u32 *val);
-       int  (*scr_write)(struct ata_port *ap, unsigned int sc_reg, u32 val);
+       int  (*scr_read)(struct ata_link *link, unsigned int sc_reg, u32 *val);
+       int  (*scr_write)(struct ata_link *link, unsigned int sc_reg, u32 val);
        void (*pmp_attach)(struct ata_port *ap);
        void (*pmp_detach)(struct ata_port *ap);
        int  (*enable_pm)(struct ata_port *ap, enum link_pm policy);
@@ -895,6 +905,7 @@ extern void ata_port_disable(struct ata_port *);
 extern struct ata_host *ata_host_alloc(struct device *dev, int max_ports);
 extern struct ata_host *ata_host_alloc_pinfo(struct device *dev,
                        const struct ata_port_info * const * ppi, int n_ports);
+extern int ata_slave_link_init(struct ata_port *ap);
 extern int ata_host_start(struct ata_host *host);
 extern int ata_host_register(struct ata_host *host,
                             struct scsi_host_template *sht);
@@ -920,8 +931,8 @@ extern int sata_scr_valid(struct ata_link *link);
 extern int sata_scr_read(struct ata_link *link, int reg, u32 *val);
 extern int sata_scr_write(struct ata_link *link, int reg, u32 val);
 extern int sata_scr_write_flush(struct ata_link *link, int reg, u32 val);
-extern int ata_link_online(struct ata_link *link);
-extern int ata_link_offline(struct ata_link *link);
+extern bool ata_link_online(struct ata_link *link);
+extern bool ata_link_offline(struct ata_link *link);
 #ifdef CONFIG_PM
 extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg);
 extern void ata_host_resume(struct ata_host *host);
@@ -1098,6 +1109,7 @@ extern void ata_std_error_handler(struct ata_port *ap);
  */
 extern const struct ata_port_operations ata_base_port_ops;
 extern const struct ata_port_operations sata_port_ops;
+extern struct device_attribute *ata_common_sdev_attrs[];
 
 #define ATA_BASE_SHT(drv_name)                                 \
        .module                 = THIS_MODULE,                  \
@@ -1112,7 +1124,8 @@ extern const struct ata_port_operations sata_port_ops;
        .proc_name              = drv_name,                     \
        .slave_configure        = ata_scsi_slave_config,        \
        .slave_destroy          = ata_scsi_slave_destroy,       \
-       .bios_param             = ata_std_bios_param
+       .bios_param             = ata_std_bios_param,           \
+       .sdev_attrs             = ata_common_sdev_attrs
 
 #define ATA_NCQ_SHT(drv_name)                                  \
        ATA_BASE_SHT(drv_name),                                 \
@@ -1134,7 +1147,7 @@ static inline bool sata_pmp_attached(struct ata_port *ap)
 
 static inline int ata_is_host_link(const struct ata_link *link)
 {
-       return link == &link->ap->link;
+       return link == &link->ap->link || link == link->ap->slave_link;
 }
 #else /* CONFIG_SATA_PMP */
 static inline bool sata_pmp_supported(struct ata_port *ap)
@@ -1167,7 +1180,7 @@ static inline int sata_srst_pmp(struct ata_link *link)
        printk("%sata%u: "fmt, lv, (ap)->print_id , ##args)
 
 #define ata_link_printk(link, lv, fmt, args...) do { \
-       if (sata_pmp_attached((link)->ap)) \
+       if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link)    \
                printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id,   \
                       (link)->pmp , ##args); \
        else \
@@ -1265,34 +1278,17 @@ static inline int ata_link_active(struct ata_link *link)
        return ata_tag_valid(link->active_tag) || link->sactive;
 }
 
-static inline struct ata_link *ata_port_first_link(struct ata_port *ap)
-{
-       if (sata_pmp_attached(ap))
-               return ap->pmp_link;
-       return &ap->link;
-}
-
-static inline struct ata_link *ata_port_next_link(struct ata_link *link)
-{
-       struct ata_port *ap = link->ap;
-
-       if (ata_is_host_link(link)) {
-               if (!sata_pmp_attached(ap))
-                       return NULL;
-               return ap->pmp_link;
-       }
-
-       if (++link < ap->nr_pmp_links + ap->pmp_link)
-               return link;
-       return NULL;
-}
+extern struct ata_link *__ata_port_next_link(struct ata_port *ap,
+                                            struct ata_link *link,
+                                            bool dev_only);
 
-#define __ata_port_for_each_link(lk, ap) \
-       for ((lk) = &(ap)->link; (lk); (lk) = ata_port_next_link(lk))
+#define __ata_port_for_each_link(link, ap) \
+       for ((link) = __ata_port_next_link((ap), NULL, false); (link); \
+            (link) = __ata_port_next_link((ap), (link), false))
 
 #define ata_port_for_each_link(link, ap) \
-       for ((link) = ata_port_first_link(ap); (link); \
-            (link) = ata_port_next_link(link))
+       for ((link) = __ata_port_next_link((ap), NULL, true); (link); \
+            (link) = __ata_port_next_link((ap), (link), true))
 
 #define ata_link_for_each_dev(dev, link) \
        for ((dev) = (link)->device; \
index 53d5fafd85c30a61e381f7d3762fa6a3841aca6c..88249452b935befbc53985e9eb6c997b557346d8 100644 (file)
 
 #define VIOTAPE_MAJOR          230
 
+#define BLOCK_EXT_MAJOR                259
+
 #endif
index 310e616064158d68afb3e3fcdfcc31a56421b1bb..8b4aa0523db76d22f821d07037e36bdcf2eb62be 100644 (file)
@@ -41,6 +41,8 @@ struct mtd_blktrans_ops {
                    unsigned long block, char *buffer);
        int (*writesect)(struct mtd_blktrans_dev *dev,
                     unsigned long block, char *buffer);
+       int (*discard)(struct mtd_blktrans_dev *dev,
+                      unsigned long block, unsigned nr_blocks);
 
        /* Block layer ioctls */
        int (*getgeo)(struct mtd_blktrans_dev *dev, struct hd_geometry *geo);
index da2698b0fdd1d0989e5f1e0c2739262d002eb3df..b86fa2ffca0c3ca5f613b4b63b79a2260310b9d3 100644 (file)
@@ -213,9 +213,16 @@ static inline int notifier_to_errno(int ret)
 #define CPU_DOWN_FAILED                0x0006 /* CPU (unsigned)v NOT going down */
 #define CPU_DEAD               0x0007 /* CPU (unsigned)v dead */
 #define CPU_DYING              0x0008 /* CPU (unsigned)v not running any task,
-                                       * not handling interrupts, soon dead */
+                                       * not handling interrupts, soon dead.
+                                       * Called on the dying cpu, interrupts
+                                       * are already disabled. Must not
+                                       * sleep, must not fail */
 #define CPU_POST_DEAD          0x0009 /* CPU (unsigned)v dead, cpu_hotplug
                                        * lock is dropped */
+#define CPU_STARTING           0x000A /* CPU (unsigned)v soon running.
+                                       * Called on the new cpu, just before
+                                       * enabling interrupts. Must not sleep,
+                                       * must not fail */
 
 /* Used for CPU hotplug events occuring while tasks are frozen due to a suspend
  * operation in progress
@@ -229,6 +236,7 @@ static inline int notifier_to_errno(int ret)
 #define CPU_DOWN_FAILED_FROZEN (CPU_DOWN_FAILED | CPU_TASKS_FROZEN)
 #define CPU_DEAD_FROZEN                (CPU_DEAD | CPU_TASKS_FROZEN)
 #define CPU_DYING_FROZEN       (CPU_DYING | CPU_TASKS_FROZEN)
+#define CPU_STARTING_FROZEN    (CPU_STARTING | CPU_TASKS_FROZEN)
 
 /* Hibernation and suspend events */
 #define PM_HIBERNATION_PREPARE 0x0001 /* Going to hibernate */
index 5afc1b23346d1f04536ea9339c1790b1cceeef3a..cf793bbbd05e18e6d87e98dd1e3e4f9df767d8d6 100644 (file)
@@ -104,8 +104,8 @@ struct prop_local_single {
         * snapshot of the last seen global state
         * and a lock protecting this state
         */
-       int shift;
        unsigned long period;
+       int shift;
        spinlock_t lock;                /* protect the snapshot state */
 };
 
index 3d9120c5ad1589a0da722e514c370c0a3f1c4fe4..5d0819ee442a471e840b37a5ea1c35ee13030d25 100644 (file)
@@ -451,8 +451,8 @@ struct signal_struct {
         * - everyone except group_exit_task is stopped during signal delivery
         *   of fatal signals, group_exit_task processes the signal.
         */
-       struct task_struct      *group_exit_task;
        int                     notify_count;
+       struct task_struct      *group_exit_task;
 
        /* thread group stop support, overloads group_exit_code too */
        int                     group_stop_count;
@@ -824,6 +824,9 @@ struct sched_domain {
        unsigned int ttwu_move_affine;
        unsigned int ttwu_move_balance;
 #endif
+#ifdef CONFIG_SCHED_DEBUG
+       char *name;
+#endif
 };
 
 extern void partition_sched_domains(int ndoms_new, cpumask_t *doms_new,
@@ -897,7 +900,7 @@ struct sched_class {
        void (*yield_task) (struct rq *rq);
        int  (*select_task_rq)(struct task_struct *p, int sync);
 
-       void (*check_preempt_curr) (struct rq *rq, struct task_struct *p);
+       void (*check_preempt_curr) (struct rq *rq, struct task_struct *p, int sync);
 
        struct task_struct * (*pick_next_task) (struct rq *rq);
        void (*put_prev_task) (struct rq *rq, struct task_struct *p);
@@ -1010,8 +1013,8 @@ struct sched_entity {
 
 struct sched_rt_entity {
        struct list_head run_list;
-       unsigned int time_slice;
        unsigned long timeout;
+       unsigned int time_slice;
        int nr_cpus_allowed;
 
        struct sched_rt_entity *back;
index 80c4d002864cb2f3e9db8ebb575de2baeafe47c8..f5c4a51eb42ea9ec97f460e14a11c24850de82be 100644 (file)
@@ -1560,11 +1560,6 @@ struct security_operations {
 extern int security_init(void);
 extern int security_module_enable(struct security_operations *ops);
 extern int register_security(struct security_operations *ops);
-extern struct dentry *securityfs_create_file(const char *name, mode_t mode,
-                                            struct dentry *parent, void *data,
-                                            const struct file_operations *fops);
-extern struct dentry *securityfs_create_dir(const char *name, struct dentry *parent);
-extern void securityfs_remove(struct dentry *dentry);
 
 /* Security operations */
 int security_ptrace_may_access(struct task_struct *child, unsigned int mode);
@@ -2424,25 +2419,6 @@ static inline int security_netlink_recv(struct sk_buff *skb, int cap)
        return cap_netlink_recv(skb, cap);
 }
 
-static inline struct dentry *securityfs_create_dir(const char *name,
-                                       struct dentry *parent)
-{
-       return ERR_PTR(-ENODEV);
-}
-
-static inline struct dentry *securityfs_create_file(const char *name,
-                                               mode_t mode,
-                                               struct dentry *parent,
-                                               void *data,
-                                               const struct file_operations *fops)
-{
-       return ERR_PTR(-ENODEV);
-}
-
-static inline void securityfs_remove(struct dentry *dentry)
-{
-}
-
 static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
 {
        return -EOPNOTSUPP;
@@ -2806,5 +2782,35 @@ static inline void security_audit_rule_free(void *lsmrule)
 #endif /* CONFIG_SECURITY */
 #endif /* CONFIG_AUDIT */
 
+#ifdef CONFIG_SECURITYFS
+
+extern struct dentry *securityfs_create_file(const char *name, mode_t mode,
+                                            struct dentry *parent, void *data,
+                                            const struct file_operations *fops);
+extern struct dentry *securityfs_create_dir(const char *name, struct dentry *parent);
+extern void securityfs_remove(struct dentry *dentry);
+
+#else /* CONFIG_SECURITYFS */
+
+static inline struct dentry *securityfs_create_dir(const char *name,
+                                                  struct dentry *parent)
+{
+       return ERR_PTR(-ENODEV);
+}
+
+static inline struct dentry *securityfs_create_file(const char *name,
+                                                   mode_t mode,
+                                                   struct dentry *parent,
+                                                   void *data,
+                                                   const struct file_operations *fops)
+{
+       return ERR_PTR(-ENODEV);
+}
+
+static inline void securityfs_remove(struct dentry *dentry)
+{}
+
+#endif
+
 #endif /* ! __LINUX_SECURITY_H */
 
diff --git a/include/linux/string_helpers.h b/include/linux/string_helpers.h
new file mode 100644 (file)
index 0000000..a3eb2f6
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef _LINUX_STRING_HELPERS_H_
+#define _LINUX_STRING_HELPERS_H_
+
+#include <linux/types.h>
+
+/* Descriptions of the types of units to
+ * print in */
+enum string_size_units {
+       STRING_UNITS_10,        /* use powers of 10^3 (standard SI) */
+       STRING_UNITS_2,         /* use binary powers of 2^10 */
+};
+
+int string_get_size(u64 size, enum string_size_units units,
+                   char *buf, int len);
+
+#endif
index f9f6e793575c0b7114c3162b25e430978977d2eb..855bf95963e7e37e792ecf8485b66f2093efe2b7 100644 (file)
@@ -75,7 +75,6 @@ struct scsi_cmnd {
 
        int retries;
        int allowed;
-       int timeout_per_command;
 
        unsigned char prot_op;
        unsigned char prot_type;
@@ -86,7 +85,6 @@ struct scsi_cmnd {
        /* These elements define the operation we are about to perform */
        unsigned char *cmnd;
 
-       struct timer_list eh_timeout;   /* Used to time out the command. */
 
        /* These elements define the operation we ultimately want to perform */
        struct scsi_data_buffer sdb;
@@ -139,7 +137,6 @@ extern void scsi_put_command(struct scsi_cmnd *);
 extern void __scsi_put_command(struct Scsi_Host *, struct scsi_cmnd *,
                               struct device *);
 extern void scsi_finish_command(struct scsi_cmnd *cmd);
-extern void scsi_req_abort_cmd(struct scsi_cmnd *cmd);
 
 extern void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count,
                                 size_t *offset, size_t *len);
index 80b2e93c29360887eb55f65afd543c76e5b225cf..b49e725be0390a94be15fa4d6a3e2ce6acabe8c8 100644 (file)
@@ -42,9 +42,11 @@ enum scsi_device_state {
                                 * originate in the mid-layer) */
        SDEV_OFFLINE,           /* Device offlined (by error handling or
                                 * user request */
-       SDEV_BLOCK,             /* Device blocked by scsi lld.  No scsi 
-                                * commands from user or midlayer should be issued
-                                * to the scsi lld. */
+       SDEV_BLOCK,             /* Device blocked by scsi lld.  No
+                                * scsi commands from user or midlayer
+                                * should be issued to the scsi
+                                * lld. */
+       SDEV_CREATED_BLOCK,     /* same as above but for created devices */
 };
 
 enum scsi_device_event {
@@ -384,10 +386,23 @@ static inline unsigned int sdev_id(struct scsi_device *sdev)
 #define scmd_id(scmd) sdev_id((scmd)->device)
 #define scmd_channel(scmd) sdev_channel((scmd)->device)
 
+/*
+ * checks for positions of the SCSI state machine
+ */
 static inline int scsi_device_online(struct scsi_device *sdev)
 {
        return sdev->sdev_state != SDEV_OFFLINE;
 }
+static inline int scsi_device_blocked(struct scsi_device *sdev)
+{
+       return sdev->sdev_state == SDEV_BLOCK ||
+               sdev->sdev_state == SDEV_CREATED_BLOCK;
+}
+static inline int scsi_device_created(struct scsi_device *sdev)
+{
+       return sdev->sdev_state == SDEV_CREATED ||
+               sdev->sdev_state == SDEV_CREATED_BLOCK;
+}
 
 /* accessor functions for the SCSI parameters */
 static inline int scsi_device_sync(struct scsi_device *sdev)
index 44a55d1bf530c070e86eb8381901a3ba63dfd51c..d123ca84e732bf711fb965c66db8017ad468ec6a 100644 (file)
@@ -43,13 +43,6 @@ struct blk_queue_tags;
 #define DISABLE_CLUSTERING 0
 #define ENABLE_CLUSTERING 1
 
-enum scsi_eh_timer_return {
-       EH_NOT_HANDLED,
-       EH_HANDLED,
-       EH_RESET_TIMER,
-};
-
-
 struct scsi_host_template {
        struct module *module;
        const char *name;
@@ -347,7 +340,7 @@ struct scsi_host_template {
         *
         * Status: OPTIONAL
         */
-       enum scsi_eh_timer_return (* eh_timed_out)(struct scsi_cmnd *);
+       enum blk_eh_timer_return (*eh_timed_out)(struct scsi_cmnd *);
 
        /*
         * Name of proc directory
index 8c1470cc82096631cb370f1069c619ebf1a2ca54..536752c40d410a3d05e56ee401df88735b3c497d 100644 (file)
@@ -22,6 +22,9 @@
 #ifndef SCSI_NETLINK_H
 #define SCSI_NETLINK_H
 
+#include <linux/netlink.h>
+
+
 /*
  * This file intended to be included by both kernel and user space
  */
@@ -55,7 +58,41 @@ struct scsi_nl_hdr {
 #define SCSI_NL_TRANSPORT_FC                   1
 #define SCSI_NL_MAX_TRANSPORTS                 2
 
-/* scsi_nl_hdr->msgtype values are defined in each transport */
+/* Transport-based scsi_nl_hdr->msgtype values are defined in each transport */
+
+/*
+ * GENERIC SCSI scsi_nl_hdr->msgtype Values
+ */
+       /* kernel -> user */
+#define SCSI_NL_SHOST_VENDOR                   0x0001
+       /* user -> kernel */
+/* SCSI_NL_SHOST_VENDOR msgtype is kernel->user and user->kernel */
+
+
+/*
+ * Message Structures :
+ */
+
+/* macro to round up message lengths to 8byte boundary */
+#define SCSI_NL_MSGALIGN(len)          (((len) + 7) & ~7)
+
+
+/*
+ * SCSI HOST Vendor Unique messages :
+ *   SCSI_NL_SHOST_VENDOR
+ *
+ * Note: The Vendor Unique message payload will begin directly after
+ *      this structure, with the length of the payload per vmsg_datalen.
+ *
+ * Note: When specifying vendor_id, be sure to read the Vendor Type and ID
+ *   formatting requirements specified below
+ */
+struct scsi_nl_host_vendor_msg {
+       struct scsi_nl_hdr snlh;                /* must be 1st element ! */
+       uint64_t vendor_id;
+       uint16_t host_no;
+       uint16_t vmsg_datalen;
+} __attribute__((aligned(sizeof(uint64_t))));
 
 
 /*
@@ -83,5 +120,28 @@ struct scsi_nl_hdr {
        }
 
 
+#ifdef __KERNEL__
+
+#include <scsi/scsi_host.h>
+
+/* Exported Kernel Interfaces */
+int scsi_nl_add_transport(u8 tport,
+        int (*msg_handler)(struct sk_buff *),
+       void (*event_handler)(struct notifier_block *, unsigned long, void *));
+void scsi_nl_remove_transport(u8 tport);
+
+int scsi_nl_add_driver(u64 vendor_id, struct scsi_host_template *hostt,
+       int (*nlmsg_handler)(struct Scsi_Host *shost, void *payload,
+                                u32 len, u32 pid),
+       void (*nlevt_handler)(struct notifier_block *nb,
+                                unsigned long event, void *notify_ptr));
+void scsi_nl_remove_driver(u64 vendor_id);
+
+void scsi_nl_send_transport_msg(u32 pid, struct scsi_nl_hdr *hdr);
+int scsi_nl_send_vendor_msg(u32 pid, unsigned short host_no, u64 vendor_id,
+                        char *data_buf, u32 data_len);
+
+#endif /* __KERNEL__ */
+
 #endif /* SCSI_NETLINK_H */
 
index 490bd13a634cc7eff4e61bfab5104b1e28047e2a..0de32cd4e8a7c21d3a931c8d81381577b9853bb4 100644 (file)
@@ -21,6 +21,7 @@
 #define SCSI_TRANSPORT_H
 
 #include <linux/transport_class.h>
+#include <linux/blkdev.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_device.h>
 
@@ -64,7 +65,7 @@ struct scsi_transport_template {
         *                      begin counting again
         * EH_NOT_HANDLED       Begin normal error recovery
         */
-       enum scsi_eh_timer_return (* eh_timed_out)(struct scsi_cmnd *);
+       enum blk_eh_timer_return (*eh_timed_out)(struct scsi_cmnd *);
 
        /*
         * Used as callback for the completion of i_t_nexus request
index 878373c32ef7e434bdb6c840ca15b4ec0412d550..21018a4df452f3e7a5b96e06f212408615f814c4 100644 (file)
@@ -167,6 +167,26 @@ enum fc_tgtid_binding_type  {
 struct device_attribute dev_attr_vport_##_name =       \
        __ATTR(_name,_mode,_show,_store)
 
+/*
+ * fc_vport_identifiers: This set of data contains all elements
+ * to uniquely identify and instantiate a FC virtual port.
+ *
+ * Notes:
+ *   symbolic_name: The driver is to append the symbolic_name string data
+ *      to the symbolic_node_name data that it generates by default.
+ *      the resulting combination should then be registered with the switch.
+ *      It is expected that things like Xen may stuff a VM title into
+ *      this field.
+ */
+#define FC_VPORT_SYMBOLIC_NAMELEN              64
+struct fc_vport_identifiers {
+       u64 node_name;
+       u64 port_name;
+       u32 roles;
+       bool disable;
+       enum fc_port_type vport_type;   /* only FC_PORTTYPE_NPIV allowed */
+       char symbolic_name[FC_VPORT_SYMBOLIC_NAMELEN];
+};
 
 /*
  * FC Virtual Port Attributes
@@ -197,7 +217,6 @@ struct device_attribute dev_attr_vport_##_name =    \
  * managed by the transport w/o driver interaction.
  */
 
-#define FC_VPORT_SYMBOLIC_NAMELEN              64
 struct fc_vport {
        /* Fixed Attributes */
 
@@ -732,6 +751,8 @@ void fc_host_post_vendor_event(struct Scsi_Host *shost, u32 event_number,
         *   be sure to read the Vendor Type and ID formatting requirements
         *   specified in scsi_netlink.h
         */
+struct fc_vport *fc_vport_create(struct Scsi_Host *shost, int channel,
+               struct fc_vport_identifiers *);
 int fc_vport_terminate(struct fc_vport *vport);
 
 #endif /* SCSI_TRANSPORT_FC_H */
index 3715feb8446d5c84796310e975d4948fd88df9ea..d055b1914c3d3b696237a04bb352ed5dbb7e14c6 100644 (file)
@@ -263,6 +263,10 @@ retry:
                printk("Please append a correct \"root=\" boot option; here are the available partitions:\n");
 
                printk_all_partitions();
+#ifdef CONFIG_DEBUG_BLOCK_EXT_DEVT
+               printk("DEBUG_BLOCK_EXT_DEVT is enabled, you need to specify "
+                      "explicit textual name for \"root=\" boot option.\n");
+#endif
                panic("VFS: Unable to mount root fs on %s", b);
        }
 
index f17e9854c24612e1e3f83b389f48224eb2d7b807..86d49045daed050ee3e1c3d18a8d80d8b1793b85 100644 (file)
@@ -199,13 +199,14 @@ static int __ref take_cpu_down(void *_param)
        struct take_cpu_down_param *param = _param;
        int err;
 
-       raw_notifier_call_chain(&cpu_chain, CPU_DYING | param->mod,
-                               param->hcpu);
        /* Ensure this CPU doesn't handle any more interrupts. */
        err = __cpu_disable();
        if (err < 0)
                return err;
 
+       raw_notifier_call_chain(&cpu_chain, CPU_DYING | param->mod,
+                               param->hcpu);
+
        /* Force idle task to run as soon as we yield: it should
           immediately notice cpu is offline and die quickly. */
        sched_idle_next();
@@ -453,6 +454,25 @@ out:
 }
 #endif /* CONFIG_PM_SLEEP_SMP */
 
+/**
+ * notify_cpu_starting(cpu) - call the CPU_STARTING notifiers
+ * @cpu: cpu that just started
+ *
+ * This function calls the cpu_chain notifiers with CPU_STARTING.
+ * It must be called by the arch code on the new cpu, before the new cpu
+ * enables interrupts and before the "boot" cpu returns from __cpu_up().
+ */
+void notify_cpu_starting(unsigned int cpu)
+{
+       unsigned long val = CPU_STARTING;
+
+#ifdef CONFIG_PM_SLEEP_SMP
+       if (cpu_isset(cpu, frozen_cpus))
+               val = CPU_STARTING_FROZEN;
+#endif /* CONFIG_PM_SLEEP_SMP */
+       raw_notifier_call_chain(&cpu_chain, val, (void *)(long)cpu);
+}
+
 #endif /* CONFIG_SMP */
 
 /*
index 827cd9adccb272f3d54a0ea8a98ba8c028cde211..eab7bd6628e0ad48ef5f1d4fcea2af05f173bae5 100644 (file)
@@ -1921,7 +1921,7 @@ static void remove_tasks_in_empty_cpuset(struct cpuset *cs)
  * that has tasks along with an empty 'mems'.  But if we did see such
  * a cpuset, we'd handle it just like we do if its 'cpus' was empty.
  */
-static void scan_for_empty_cpusets(const struct cpuset *root)
+static void scan_for_empty_cpusets(struct cpuset *root)
 {
        LIST_HEAD(queue);
        struct cpuset *cp;      /* scans cpusets being updated */
index ad1962dc0aa20cb865675e8e08e49f5b49bce1df..6f230596bd0c1d21a2c68ffbff8207e93dcd65b5 100644 (file)
@@ -204,11 +204,16 @@ void init_rt_bandwidth(struct rt_bandwidth *rt_b, u64 period, u64 runtime)
        rt_b->rt_period_timer.cb_mode = HRTIMER_CB_IRQSAFE_UNLOCKED;
 }
 
+static inline int rt_bandwidth_enabled(void)
+{
+       return sysctl_sched_rt_runtime >= 0;
+}
+
 static void start_rt_bandwidth(struct rt_bandwidth *rt_b)
 {
        ktime_t now;
 
-       if (rt_b->rt_runtime == RUNTIME_INF)
+       if (rt_bandwidth_enabled() && rt_b->rt_runtime == RUNTIME_INF)
                return;
 
        if (hrtimer_active(&rt_b->rt_period_timer))
@@ -298,9 +303,9 @@ static DEFINE_PER_CPU(struct cfs_rq, init_cfs_rq) ____cacheline_aligned_in_smp;
 static DEFINE_PER_CPU(struct sched_rt_entity, init_sched_rt_entity);
 static DEFINE_PER_CPU(struct rt_rq, init_rt_rq) ____cacheline_aligned_in_smp;
 #endif /* CONFIG_RT_GROUP_SCHED */
-#else /* !CONFIG_FAIR_GROUP_SCHED */
+#else /* !CONFIG_USER_SCHED */
 #define root_task_group init_task_group
-#endif /* CONFIG_FAIR_GROUP_SCHED */
+#endif /* CONFIG_USER_SCHED */
 
 /* task_group_lock serializes add/remove of task groups and also changes to
  * a task group's cpu shares.
@@ -604,9 +609,9 @@ struct rq {
 
 static DEFINE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues);
 
-static inline void check_preempt_curr(struct rq *rq, struct task_struct *p)
+static inline void check_preempt_curr(struct rq *rq, struct task_struct *p, int sync)
 {
-       rq->curr->sched_class->check_preempt_curr(rq, p);
+       rq->curr->sched_class->check_preempt_curr(rq, p, sync);
 }
 
 static inline int cpu_of(struct rq *rq)
@@ -1102,7 +1107,7 @@ static void hrtick_start(struct rq *rq, u64 delay)
        hrtimer_start(&rq->hrtick_timer, ns_to_ktime(delay), HRTIMER_MODE_REL);
 }
 
-static void init_hrtick(void)
+static inline void init_hrtick(void)
 {
 }
 #endif /* CONFIG_SMP */
@@ -1121,7 +1126,7 @@ static void init_rq_hrtick(struct rq *rq)
        rq->hrtick_timer.function = hrtick;
        rq->hrtick_timer.cb_mode = HRTIMER_CB_IRQSAFE_PERCPU;
 }
-#else
+#else  /* CONFIG_SCHED_HRTICK */
 static inline void hrtick_clear(struct rq *rq)
 {
 }
@@ -1133,7 +1138,7 @@ static inline void init_rq_hrtick(struct rq *rq)
 static inline void init_hrtick(void)
 {
 }
-#endif
+#endif /* CONFIG_SCHED_HRTICK */
 
 /*
  * resched_task - mark a task 'to be rescheduled now'.
@@ -1380,38 +1385,24 @@ static inline void dec_cpu_load(struct rq *rq, unsigned long load)
        update_load_sub(&rq->load, load);
 }
 
-#ifdef CONFIG_SMP
-static unsigned long source_load(int cpu, int type);
-static unsigned long target_load(int cpu, int type);
-static int task_hot(struct task_struct *p, u64 now, struct sched_domain *sd);
-
-static unsigned long cpu_avg_load_per_task(int cpu)
-{
-       struct rq *rq = cpu_rq(cpu);
-
-       if (rq->nr_running)
-               rq->avg_load_per_task = rq->load.weight / rq->nr_running;
-
-       return rq->avg_load_per_task;
-}
-
-#ifdef CONFIG_FAIR_GROUP_SCHED
-
-typedef void (*tg_visitor)(struct task_group *, int, struct sched_domain *);
+#if (defined(CONFIG_SMP) && defined(CONFIG_FAIR_GROUP_SCHED)) || defined(CONFIG_RT_GROUP_SCHED)
+typedef int (*tg_visitor)(struct task_group *, void *);
 
 /*
  * Iterate the full tree, calling @down when first entering a node and @up when
  * leaving it for the final time.
  */
-static void
-walk_tg_tree(tg_visitor down, tg_visitor up, int cpu, struct sched_domain *sd)
+static int walk_tg_tree(tg_visitor down, tg_visitor up, void *data)
 {
        struct task_group *parent, *child;
+       int ret;
 
        rcu_read_lock();
        parent = &root_task_group;
 down:
-       (*down)(parent, cpu, sd);
+       ret = (*down)(parent, data);
+       if (ret)
+               goto out_unlock;
        list_for_each_entry_rcu(child, &parent->children, siblings) {
                parent = child;
                goto down;
@@ -1419,15 +1410,43 @@ down:
 up:
                continue;
        }
-       (*up)(parent, cpu, sd);
+       ret = (*up)(parent, data);
+       if (ret)
+               goto out_unlock;
 
        child = parent;
        parent = parent->parent;
        if (parent)
                goto up;
+out_unlock:
        rcu_read_unlock();
+
+       return ret;
 }
 
+static int tg_nop(struct task_group *tg, void *data)
+{
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_SMP
+static unsigned long source_load(int cpu, int type);
+static unsigned long target_load(int cpu, int type);
+static int task_hot(struct task_struct *p, u64 now, struct sched_domain *sd);
+
+static unsigned long cpu_avg_load_per_task(int cpu)
+{
+       struct rq *rq = cpu_rq(cpu);
+
+       if (rq->nr_running)
+               rq->avg_load_per_task = rq->load.weight / rq->nr_running;
+
+       return rq->avg_load_per_task;
+}
+
+#ifdef CONFIG_FAIR_GROUP_SCHED
+
 static void __set_se_shares(struct sched_entity *se, unsigned long shares);
 
 /*
@@ -1486,11 +1505,11 @@ __update_group_shares_cpu(struct task_group *tg, int cpu,
  * This needs to be done in a bottom-up fashion because the rq weight of a
  * parent group depends on the shares of its child groups.
  */
-static void
-tg_shares_up(struct task_group *tg, int cpu, struct sched_domain *sd)
+static int tg_shares_up(struct task_group *tg, void *data)
 {
        unsigned long rq_weight = 0;
        unsigned long shares = 0;
+       struct sched_domain *sd = data;
        int i;
 
        for_each_cpu_mask(i, sd->span) {
@@ -1515,6 +1534,8 @@ tg_shares_up(struct task_group *tg, int cpu, struct sched_domain *sd)
                __update_group_shares_cpu(tg, i, shares, rq_weight);
                spin_unlock_irqrestore(&rq->lock, flags);
        }
+
+       return 0;
 }
 
 /*
@@ -1522,10 +1543,10 @@ tg_shares_up(struct task_group *tg, int cpu, struct sched_domain *sd)
  * This needs to be done in a top-down fashion because the load of a child
  * group is a fraction of its parents load.
  */
-static void
-tg_load_down(struct task_group *tg, int cpu, struct sched_domain *sd)
+static int tg_load_down(struct task_group *tg, void *data)
 {
        unsigned long load;
+       long cpu = (long)data;
 
        if (!tg->parent) {
                load = cpu_rq(cpu)->load.weight;
@@ -1536,11 +1557,8 @@ tg_load_down(struct task_group *tg, int cpu, struct sched_domain *sd)
        }
 
        tg->cfs_rq[cpu]->h_load = load;
-}
 
-static void
-tg_nop(struct task_group *tg, int cpu, struct sched_domain *sd)
-{
+       return 0;
 }
 
 static void update_shares(struct sched_domain *sd)
@@ -1550,7 +1568,7 @@ static void update_shares(struct sched_domain *sd)
 
        if (elapsed >= (s64)(u64)sysctl_sched_shares_ratelimit) {
                sd->last_update = now;
-               walk_tg_tree(tg_nop, tg_shares_up, 0, sd);
+               walk_tg_tree(tg_nop, tg_shares_up, sd);
        }
 }
 
@@ -1561,9 +1579,9 @@ static void update_shares_locked(struct rq *rq, struct sched_domain *sd)
        spin_lock(&rq->lock);
 }
 
-static void update_h_load(int cpu)
+static void update_h_load(long cpu)
 {
-       walk_tg_tree(tg_load_down, tg_nop, cpu, NULL);
+       walk_tg_tree(tg_load_down, tg_nop, (void *)cpu);
 }
 
 #else
@@ -1921,11 +1939,8 @@ unsigned long wait_task_inactive(struct task_struct *p, long match_state)
                running = task_running(rq, p);
                on_rq = p->se.on_rq;
                ncsw = 0;
-               if (!match_state || p->state == match_state) {
-                       ncsw = p->nivcsw + p->nvcsw;
-                       if (unlikely(!ncsw))
-                               ncsw = 1;
-               }
+               if (!match_state || p->state == match_state)
+                       ncsw = p->nvcsw | LONG_MIN; /* sets MSB */
                task_rq_unlock(rq, &flags);
 
                /*
@@ -2285,7 +2300,7 @@ out_running:
        trace_mark(kernel_sched_wakeup,
                "pid %d state %ld ## rq %p task %p rq->curr %p",
                p->pid, p->state, rq, p, rq->curr);
-       check_preempt_curr(rq, p);
+       check_preempt_curr(rq, p, sync);
 
        p->state = TASK_RUNNING;
 #ifdef CONFIG_SMP
@@ -2420,7 +2435,7 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags)
        trace_mark(kernel_sched_wakeup_new,
                "pid %d state %ld ## rq %p task %p rq->curr %p",
                p->pid, p->state, rq, p, rq->curr);
-       check_preempt_curr(rq, p);
+       check_preempt_curr(rq, p, 0);
 #ifdef CONFIG_SMP
        if (p->sched_class->task_wake_up)
                p->sched_class->task_wake_up(rq, p);
@@ -2880,7 +2895,7 @@ static void pull_task(struct rq *src_rq, struct task_struct *p,
         * Note that idle threads have a prio of MAX_PRIO, for this test
         * to be always true for them.
         */
-       check_preempt_curr(this_rq, p);
+       check_preempt_curr(this_rq, p, 0);
 }
 
 /*
@@ -4627,6 +4642,15 @@ __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr_exclusive)
 }
 EXPORT_SYMBOL_GPL(__wake_up_sync);     /* For internal use only */
 
+/**
+ * complete: - signals a single thread waiting on this completion
+ * @x:  holds the state of this particular completion
+ *
+ * This will wake up a single thread waiting on this completion. Threads will be
+ * awakened in the same order in which they were queued.
+ *
+ * See also complete_all(), wait_for_completion() and related routines.
+ */
 void complete(struct completion *x)
 {
        unsigned long flags;
@@ -4638,6 +4662,12 @@ void complete(struct completion *x)
 }
 EXPORT_SYMBOL(complete);
 
+/**
+ * complete_all: - signals all threads waiting on this completion
+ * @x:  holds the state of this particular completion
+ *
+ * This will wake up all threads waiting on this particular completion event.
+ */
 void complete_all(struct completion *x)
 {
        unsigned long flags;
@@ -4658,10 +4688,7 @@ do_wait_for_common(struct completion *x, long timeout, int state)
                wait.flags |= WQ_FLAG_EXCLUSIVE;
                __add_wait_queue_tail(&x->wait, &wait);
                do {
-                       if ((state == TASK_INTERRUPTIBLE &&
-                            signal_pending(current)) ||
-                           (state == TASK_KILLABLE &&
-                            fatal_signal_pending(current))) {
+                       if (signal_pending_state(state, current)) {
                                timeout = -ERESTARTSYS;
                                break;
                        }
@@ -4689,12 +4716,31 @@ wait_for_common(struct completion *x, long timeout, int state)
        return timeout;
 }
 
+/**
+ * wait_for_completion: - waits for completion of a task
+ * @x:  holds the state of this particular completion
+ *
+ * This waits to be signaled for completion of a specific task. It is NOT
+ * interruptible and there is no timeout.
+ *
+ * See also similar routines (i.e. wait_for_completion_timeout()) with timeout
+ * and interrupt capability. Also see complete().
+ */
 void __sched wait_for_completion(struct completion *x)
 {
        wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_UNINTERRUPTIBLE);
 }
 EXPORT_SYMBOL(wait_for_completion);
 
+/**
+ * wait_for_completion_timeout: - waits for completion of a task (w/timeout)
+ * @x:  holds the state of this particular completion
+ * @timeout:  timeout value in jiffies
+ *
+ * This waits for either a completion of a specific task to be signaled or for a
+ * specified timeout to expire. The timeout is in jiffies. It is not
+ * interruptible.
+ */
 unsigned long __sched
 wait_for_completion_timeout(struct completion *x, unsigned long timeout)
 {
@@ -4702,6 +4748,13 @@ wait_for_completion_timeout(struct completion *x, unsigned long timeout)
 }
 EXPORT_SYMBOL(wait_for_completion_timeout);
 
+/**
+ * wait_for_completion_interruptible: - waits for completion of a task (w/intr)
+ * @x:  holds the state of this particular completion
+ *
+ * This waits for completion of a specific task to be signaled. It is
+ * interruptible.
+ */
 int __sched wait_for_completion_interruptible(struct completion *x)
 {
        long t = wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_INTERRUPTIBLE);
@@ -4711,6 +4764,14 @@ int __sched wait_for_completion_interruptible(struct completion *x)
 }
 EXPORT_SYMBOL(wait_for_completion_interruptible);
 
+/**
+ * wait_for_completion_interruptible_timeout: - waits for completion (w/(to,intr))
+ * @x:  holds the state of this particular completion
+ * @timeout:  timeout value in jiffies
+ *
+ * This waits for either a completion of a specific task to be signaled or for a
+ * specified timeout to expire. It is interruptible. The timeout is in jiffies.
+ */
 unsigned long __sched
 wait_for_completion_interruptible_timeout(struct completion *x,
                                          unsigned long timeout)
@@ -4719,6 +4780,13 @@ wait_for_completion_interruptible_timeout(struct completion *x,
 }
 EXPORT_SYMBOL(wait_for_completion_interruptible_timeout);
 
+/**
+ * wait_for_completion_killable: - waits for completion of a task (killable)
+ * @x:  holds the state of this particular completion
+ *
+ * This waits to be signaled for completion of a specific task. It can be
+ * interrupted by a kill signal.
+ */
 int __sched wait_for_completion_killable(struct completion *x)
 {
        long t = wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_KILLABLE);
@@ -5121,7 +5189,8 @@ recheck:
                 * Do not allow realtime tasks into groups that have no runtime
                 * assigned.
                 */
-               if (rt_policy(policy) && task_group(p)->rt_bandwidth.rt_runtime == 0)
+               if (rt_bandwidth_enabled() && rt_policy(policy) &&
+                               task_group(p)->rt_bandwidth.rt_runtime == 0)
                        return -EPERM;
 #endif
 
@@ -5957,7 +6026,7 @@ static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu)
        set_task_cpu(p, dest_cpu);
        if (on_rq) {
                activate_task(rq_dest, p, 0);
-               check_preempt_curr(rq_dest, p);
+               check_preempt_curr(rq_dest, p, 0);
        }
 done:
        ret = 1;
@@ -6282,7 +6351,7 @@ set_table_entry(struct ctl_table *entry,
 static struct ctl_table *
 sd_alloc_ctl_domain_table(struct sched_domain *sd)
 {
-       struct ctl_table *table = sd_alloc_ctl_entry(12);
+       struct ctl_table *table = sd_alloc_ctl_entry(13);
 
        if (table == NULL)
                return NULL;
@@ -6310,7 +6379,9 @@ sd_alloc_ctl_domain_table(struct sched_domain *sd)
                sizeof(int), 0644, proc_dointvec_minmax);
        set_table_entry(&table[10], "flags", &sd->flags,
                sizeof(int), 0644, proc_dointvec_minmax);
-       /* &table[11] is terminator */
+       set_table_entry(&table[11], "name", sd->name,
+               CORENAME_MAX_SIZE, 0444, proc_dostring);
+       /* &table[12] is terminator */
 
        return table;
 }
@@ -7194,13 +7265,21 @@ static void init_sched_groups_power(int cpu, struct sched_domain *sd)
  * Non-inlined to reduce accumulated stack pressure in build_sched_domains()
  */
 
+#ifdef CONFIG_SCHED_DEBUG
+# define SD_INIT_NAME(sd, type)                sd->name = #type
+#else
+# define SD_INIT_NAME(sd, type)                do { } while (0)
+#endif
+
 #define        SD_INIT(sd, type)       sd_init_##type(sd)
+
 #define SD_INIT_FUNC(type)     \
 static noinline void sd_init_##type(struct sched_domain *sd)   \
 {                                                              \
        memset(sd, 0, sizeof(*sd));                             \
        *sd = SD_##type##_INIT;                                 \
        sd->level = SD_LV_##type;                               \
+       SD_INIT_NAME(sd, type);                                 \
 }
 
 SD_INIT_FUNC(CPU)
@@ -8242,20 +8321,25 @@ void __might_sleep(char *file, int line)
 #ifdef in_atomic
        static unsigned long prev_jiffy;        /* ratelimiting */
 
-       if ((in_atomic() || irqs_disabled()) &&
-           system_state == SYSTEM_RUNNING && !oops_in_progress) {
-               if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy)
-                       return;
-               prev_jiffy = jiffies;
-               printk(KERN_ERR "BUG: sleeping function called from invalid"
-                               " context at %s:%d\n", file, line);
-               printk("in_atomic():%d, irqs_disabled():%d\n",
-                       in_atomic(), irqs_disabled());
-               debug_show_held_locks(current);
-               if (irqs_disabled())
-                       print_irqtrace_events(current);
-               dump_stack();
-       }
+       if ((!in_atomic() && !irqs_disabled()) ||
+                   system_state != SYSTEM_RUNNING || oops_in_progress)
+               return;
+       if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy)
+               return;
+       prev_jiffy = jiffies;
+
+       printk(KERN_ERR
+               "BUG: sleeping function called from invalid context at %s:%d\n",
+                       file, line);
+       printk(KERN_ERR
+               "in_atomic(): %d, irqs_disabled(): %d, pid: %d, name: %s\n",
+                       in_atomic(), irqs_disabled(),
+                       current->pid, current->comm);
+
+       debug_show_held_locks(current);
+       if (irqs_disabled())
+               print_irqtrace_events(current);
+       dump_stack();
 #endif
 }
 EXPORT_SYMBOL(__might_sleep);
@@ -8753,73 +8837,95 @@ static DEFINE_MUTEX(rt_constraints_mutex);
 static unsigned long to_ratio(u64 period, u64 runtime)
 {
        if (runtime == RUNTIME_INF)
-               return 1ULL << 16;
+               return 1ULL << 20;
 
-       return div64_u64(runtime << 16, period);
+       return div64_u64(runtime << 20, period);
 }
 
-#ifdef CONFIG_CGROUP_SCHED
-static int __rt_schedulable(struct task_group *tg, u64 period, u64 runtime)
+/* Must be called with tasklist_lock held */
+static inline int tg_has_rt_tasks(struct task_group *tg)
 {
-       struct task_group *tgi, *parent = tg->parent;
-       unsigned long total = 0;
+       struct task_struct *g, *p;
 
-       if (!parent) {
-               if (global_rt_period() < period)
-                       return 0;
+       do_each_thread(g, p) {
+               if (rt_task(p) && rt_rq_of_se(&p->rt)->tg == tg)
+                       return 1;
+       } while_each_thread(g, p);
 
-               return to_ratio(period, runtime) <
-                       to_ratio(global_rt_period(), global_rt_runtime());
-       }
+       return 0;
+}
 
-       if (ktime_to_ns(parent->rt_bandwidth.rt_period) < period)
-               return 0;
+struct rt_schedulable_data {
+       struct task_group *tg;
+       u64 rt_period;
+       u64 rt_runtime;
+};
 
-       rcu_read_lock();
-       list_for_each_entry_rcu(tgi, &parent->children, siblings) {
-               if (tgi == tg)
-                       continue;
+static int tg_schedulable(struct task_group *tg, void *data)
+{
+       struct rt_schedulable_data *d = data;
+       struct task_group *child;
+       unsigned long total, sum = 0;
+       u64 period, runtime;
 
-               total += to_ratio(ktime_to_ns(tgi->rt_bandwidth.rt_period),
-                               tgi->rt_bandwidth.rt_runtime);
+       period = ktime_to_ns(tg->rt_bandwidth.rt_period);
+       runtime = tg->rt_bandwidth.rt_runtime;
+
+       if (tg == d->tg) {
+               period = d->rt_period;
+               runtime = d->rt_runtime;
        }
-       rcu_read_unlock();
 
-       return total + to_ratio(period, runtime) <=
-               to_ratio(ktime_to_ns(parent->rt_bandwidth.rt_period),
-                               parent->rt_bandwidth.rt_runtime);
-}
-#elif defined CONFIG_USER_SCHED
-static int __rt_schedulable(struct task_group *tg, u64 period, u64 runtime)
-{
-       struct task_group *tgi;
-       unsigned long total = 0;
-       unsigned long global_ratio =
-               to_ratio(global_rt_period(), global_rt_runtime());
+       /*
+        * Cannot have more runtime than the period.
+        */
+       if (runtime > period && runtime != RUNTIME_INF)
+               return -EINVAL;
 
-       rcu_read_lock();
-       list_for_each_entry_rcu(tgi, &task_groups, list) {
-               if (tgi == tg)
-                       continue;
+       /*
+        * Ensure we don't starve existing RT tasks.
+        */
+       if (rt_bandwidth_enabled() && !runtime && tg_has_rt_tasks(tg))
+               return -EBUSY;
+
+       total = to_ratio(period, runtime);
+
+       /*
+        * Nobody can have more than the global setting allows.
+        */
+       if (total > to_ratio(global_rt_period(), global_rt_runtime()))
+               return -EINVAL;
+
+       /*
+        * The sum of our children's runtime should not exceed our own.
+        */
+       list_for_each_entry_rcu(child, &tg->children, siblings) {
+               period = ktime_to_ns(child->rt_bandwidth.rt_period);
+               runtime = child->rt_bandwidth.rt_runtime;
+
+               if (child == d->tg) {
+                       period = d->rt_period;
+                       runtime = d->rt_runtime;
+               }
 
-               total += to_ratio(ktime_to_ns(tgi->rt_bandwidth.rt_period),
-                               tgi->rt_bandwidth.rt_runtime);
+               sum += to_ratio(period, runtime);
        }
-       rcu_read_unlock();
 
-       return total + to_ratio(period, runtime) < global_ratio;
+       if (sum > total)
+               return -EINVAL;
+
+       return 0;
 }
-#endif
 
-/* Must be called with tasklist_lock held */
-static inline int tg_has_rt_tasks(struct task_group *tg)
+static int __rt_schedulable(struct task_group *tg, u64 period, u64 runtime)
 {
-       struct task_struct *g, *p;
-       do_each_thread(g, p) {
-               if (rt_task(p) && rt_rq_of_se(&p->rt)->tg == tg)
-                       return 1;
-       } while_each_thread(g, p);
-       return 0;
+       struct rt_schedulable_data data = {
+               .tg = tg,
+               .rt_period = period,
+               .rt_runtime = runtime,
+       };
+
+       return walk_tg_tree(tg_schedulable, tg_nop, &data);
 }
 
 static int tg_set_bandwidth(struct task_group *tg,
@@ -8829,14 +8935,9 @@ static int tg_set_bandwidth(struct task_group *tg,
 
        mutex_lock(&rt_constraints_mutex);
        read_lock(&tasklist_lock);
-       if (rt_runtime == 0 && tg_has_rt_tasks(tg)) {
-               err = -EBUSY;
+       err = __rt_schedulable(tg, rt_period, rt_runtime);
+       if (err)
                goto unlock;
-       }
-       if (!__rt_schedulable(tg, rt_period, rt_runtime)) {
-               err = -EINVAL;
-               goto unlock;
-       }
 
        spin_lock_irq(&tg->rt_bandwidth.rt_runtime_lock);
        tg->rt_bandwidth.rt_period = ns_to_ktime(rt_period);
@@ -8905,19 +9006,25 @@ long sched_group_rt_period(struct task_group *tg)
 
 static int sched_rt_global_constraints(void)
 {
-       struct task_group *tg = &root_task_group;
-       u64 rt_runtime, rt_period;
+       u64 runtime, period;
        int ret = 0;
 
        if (sysctl_sched_rt_period <= 0)
                return -EINVAL;
 
-       rt_period = ktime_to_ns(tg->rt_bandwidth.rt_period);
-       rt_runtime = tg->rt_bandwidth.rt_runtime;
+       runtime = global_rt_runtime();
+       period = global_rt_period();
+
+       /*
+        * Sanity check on the sysctl variables.
+        */
+       if (runtime > period && runtime != RUNTIME_INF)
+               return -EINVAL;
 
        mutex_lock(&rt_constraints_mutex);
-       if (!__rt_schedulable(tg, rt_period, rt_runtime))
-               ret = -EINVAL;
+       read_lock(&tasklist_lock);
+       ret = __rt_schedulable(NULL, 0, 0);
+       read_unlock(&tasklist_lock);
        mutex_unlock(&rt_constraints_mutex);
 
        return ret;
@@ -8991,7 +9098,6 @@ cpu_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cgrp)
 
        if (!cgrp->parent) {
                /* This is early initialization for the top cgroup */
-               init_task_group.css.cgroup = cgrp;
                return &init_task_group.css;
        }
 
@@ -9000,9 +9106,6 @@ cpu_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cgrp)
        if (IS_ERR(tg))
                return ERR_PTR(-ENOMEM);
 
-       /* Bind the cgroup to task_group object we just created */
-       tg->css.cgroup = cgrp;
-
        return &tg->css;
 }
 
index fb8994c6d4bb4bbe90a71f89341baee3cc6e9806..18fd17172eb66bb567ca4bcc47ca6c0cea923462 100644 (file)
@@ -408,64 +408,6 @@ static u64 sched_vslice_add(struct cfs_rq *cfs_rq, struct sched_entity *se)
        return __sched_period(nr_running);
 }
 
-/*
- * The goal of calc_delta_asym() is to be asymmetrically around NICE_0_LOAD, in
- * that it favours >=0 over <0.
- *
- *   -20         |
- *               |
- *     0 --------+-------
- *             .'
- *    19     .'
- *
- */
-static unsigned long
-calc_delta_asym(unsigned long delta, struct sched_entity *se)
-{
-       struct load_weight lw = {
-               .weight = NICE_0_LOAD,
-               .inv_weight = 1UL << (WMULT_SHIFT-NICE_0_SHIFT)
-       };
-
-       for_each_sched_entity(se) {
-               struct load_weight *se_lw = &se->load;
-               unsigned long rw = cfs_rq_of(se)->load.weight;
-
-#ifdef CONFIG_FAIR_SCHED_GROUP
-               struct cfs_rq *cfs_rq = se->my_q;
-               struct task_group *tg = NULL
-
-               if (cfs_rq)
-                       tg = cfs_rq->tg;
-
-               if (tg && tg->shares < NICE_0_LOAD) {
-                       /*
-                        * scale shares to what it would have been had
-                        * tg->weight been NICE_0_LOAD:
-                        *
-                        *   weight = 1024 * shares / tg->weight
-                        */
-                       lw.weight *= se->load.weight;
-                       lw.weight /= tg->shares;
-
-                       lw.inv_weight = 0;
-
-                       se_lw = &lw;
-                       rw += lw.weight - se->load.weight;
-               } else
-#endif
-
-               if (se->load.weight < NICE_0_LOAD) {
-                       se_lw = &lw;
-                       rw += NICE_0_LOAD - se->load.weight;
-               }
-
-               delta = calc_delta_mine(delta, rw, se_lw);
-       }
-
-       return delta;
-}
-
 /*
  * Update the current task's runtime statistics. Skip current tasks that
  * are not in our scheduling class.
@@ -586,11 +528,12 @@ account_entity_enqueue(struct cfs_rq *cfs_rq, struct sched_entity *se)
        update_load_add(&cfs_rq->load, se->load.weight);
        if (!parent_entity(se))
                inc_cpu_load(rq_of(cfs_rq), se->load.weight);
-       if (entity_is_task(se))
+       if (entity_is_task(se)) {
                add_cfs_task_weight(cfs_rq, se->load.weight);
+               list_add(&se->group_node, &cfs_rq->tasks);
+       }
        cfs_rq->nr_running++;
        se->on_rq = 1;
-       list_add(&se->group_node, &cfs_rq->tasks);
 }
 
 static void
@@ -599,11 +542,12 @@ account_entity_dequeue(struct cfs_rq *cfs_rq, struct sched_entity *se)
        update_load_sub(&cfs_rq->load, se->load.weight);
        if (!parent_entity(se))
                dec_cpu_load(rq_of(cfs_rq), se->load.weight);
-       if (entity_is_task(se))
+       if (entity_is_task(se)) {
                add_cfs_task_weight(cfs_rq, -se->load.weight);
+               list_del_init(&se->group_node);
+       }
        cfs_rq->nr_running--;
        se->on_rq = 0;
-       list_del_init(&se->group_node);
 }
 
 static void enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se)
@@ -1085,7 +1029,6 @@ static long effective_load(struct task_group *tg, int cpu,
                long wl, long wg)
 {
        struct sched_entity *se = tg->se[cpu];
-       long more_w;
 
        if (!tg->parent)
                return wl;
@@ -1097,18 +1040,17 @@ static long effective_load(struct task_group *tg, int cpu,
        if (!wl && sched_feat(ASYM_EFF_LOAD))
                return wl;
 
-       /*
-        * Instead of using this increment, also add the difference
-        * between when the shares were last updated and now.
-        */
-       more_w = se->my_q->load.weight - se->my_q->rq_weight;
-       wl += more_w;
-       wg += more_w;
-
        for_each_sched_entity(se) {
-#define D(n) (likely(n) ? (n) : 1)
-
                long S, rw, s, a, b;
+               long more_w;
+
+               /*
+                * Instead of using this increment, also add the difference
+                * between when the shares were last updated and now.
+                */
+               more_w = se->my_q->load.weight - se->my_q->rq_weight;
+               wl += more_w;
+               wg += more_w;
 
                S = se->my_q->tg->shares;
                s = se->my_q->shares;
@@ -1117,7 +1059,11 @@ static long effective_load(struct task_group *tg, int cpu,
                a = S*(rw + wl);
                b = S*rw + s*wg;
 
-               wl = s*(a-b)/D(b);
+               wl = s*(a-b);
+
+               if (likely(b))
+                       wl /= b;
+
                /*
                 * Assume the group is already running and will
                 * thus already be accounted for in the weight.
@@ -1126,7 +1072,6 @@ static long effective_load(struct task_group *tg, int cpu,
                 * alter the group weight.
                 */
                wg = 0;
-#undef D
        }
 
        return wl;
@@ -1143,7 +1088,7 @@ static inline unsigned long effective_load(struct task_group *tg, int cpu,
 #endif
 
 static int
-wake_affine(struct rq *rq, struct sched_domain *this_sd, struct rq *this_rq,
+wake_affine(struct sched_domain *this_sd, struct rq *this_rq,
            struct task_struct *p, int prev_cpu, int this_cpu, int sync,
            int idx, unsigned long load, unsigned long this_load,
            unsigned int imbalance)
@@ -1158,6 +1103,11 @@ wake_affine(struct rq *rq, struct sched_domain *this_sd, struct rq *this_rq,
        if (!(this_sd->flags & SD_WAKE_AFFINE) || !sched_feat(AFFINE_WAKEUPS))
                return 0;
 
+       if (!sync && sched_feat(SYNC_WAKEUPS) &&
+           curr->se.avg_overlap < sysctl_sched_migration_cost &&
+           p->se.avg_overlap < sysctl_sched_migration_cost)
+               sync = 1;
+
        /*
         * If sync wakeup then subtract the (maximum possible)
         * effect of the currently running task from the load
@@ -1182,17 +1132,14 @@ wake_affine(struct rq *rq, struct sched_domain *this_sd, struct rq *this_rq,
         * a reasonable amount of time then attract this newly
         * woken task:
         */
-       if (sync && balanced) {
-               if (curr->se.avg_overlap < sysctl_sched_migration_cost &&
-                   p->se.avg_overlap < sysctl_sched_migration_cost)
-                       return 1;
-       }
+       if (sync && balanced)
+               return 1;
 
        schedstat_inc(p, se.nr_wakeups_affine_attempts);
        tl_per_task = cpu_avg_load_per_task(this_cpu);
 
-       if ((tl <= load && tl + target_load(prev_cpu, idx) <= tl_per_task) ||
-                       balanced) {
+       if (balanced || (tl <= load && tl + target_load(prev_cpu, idx) <=
+                       tl_per_task)) {
                /*
                 * This domain has SD_WAKE_AFFINE and
                 * p is cache cold in this domain, and
@@ -1211,16 +1158,17 @@ static int select_task_rq_fair(struct task_struct *p, int sync)
        struct sched_domain *sd, *this_sd = NULL;
        int prev_cpu, this_cpu, new_cpu;
        unsigned long load, this_load;
-       struct rq *rq, *this_rq;
+       struct rq *this_rq;
        unsigned int imbalance;
        int idx;
 
        prev_cpu        = task_cpu(p);
-       rq              = task_rq(p);
        this_cpu        = smp_processor_id();
        this_rq         = cpu_rq(this_cpu);
        new_cpu         = prev_cpu;
 
+       if (prev_cpu == this_cpu)
+               goto out;
        /*
         * 'this_sd' is the first domain that both
         * this_cpu and prev_cpu are present in:
@@ -1248,13 +1196,10 @@ static int select_task_rq_fair(struct task_struct *p, int sync)
        load = source_load(prev_cpu, idx);
        this_load = target_load(this_cpu, idx);
 
-       if (wake_affine(rq, this_sd, this_rq, p, prev_cpu, this_cpu, sync, idx,
+       if (wake_affine(this_sd, this_rq, p, prev_cpu, this_cpu, sync, idx,
                                     load, this_load, imbalance))
                return this_cpu;
 
-       if (prev_cpu == this_cpu)
-               goto out;
-
        /*
         * Start passive balancing when half the imbalance_pct
         * limit is reached.
@@ -1281,62 +1226,20 @@ static unsigned long wakeup_gran(struct sched_entity *se)
         * + nice tasks.
         */
        if (sched_feat(ASYM_GRAN))
-               gran = calc_delta_asym(sysctl_sched_wakeup_granularity, se);
-       else
-               gran = calc_delta_fair(sysctl_sched_wakeup_granularity, se);
+               gran = calc_delta_mine(gran, NICE_0_LOAD, &se->load);
 
        return gran;
 }
 
-/*
- * Should 'se' preempt 'curr'.
- *
- *             |s1
- *        |s2
- *   |s3
- *         g
- *      |<--->|c
- *
- *  w(c, s1) = -1
- *  w(c, s2) =  0
- *  w(c, s3) =  1
- *
- */
-static int
-wakeup_preempt_entity(struct sched_entity *curr, struct sched_entity *se)
-{
-       s64 gran, vdiff = curr->vruntime - se->vruntime;
-
-       if (vdiff < 0)
-               return -1;
-
-       gran = wakeup_gran(curr);
-       if (vdiff > gran)
-               return 1;
-
-       return 0;
-}
-
-/* return depth at which a sched entity is present in the hierarchy */
-static inline int depth_se(struct sched_entity *se)
-{
-       int depth = 0;
-
-       for_each_sched_entity(se)
-               depth++;
-
-       return depth;
-}
-
 /*
  * Preempt the current task with a newly woken task if needed:
  */
-static void check_preempt_wakeup(struct rq *rq, struct task_struct *p)
+static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int sync)
 {
        struct task_struct *curr = rq->curr;
        struct cfs_rq *cfs_rq = task_cfs_rq(curr);
        struct sched_entity *se = &curr->se, *pse = &p->se;
-       int se_depth, pse_depth;
+       s64 delta_exec;
 
        if (unlikely(rt_prio(p->prio))) {
                update_rq_clock(rq);
@@ -1350,6 +1253,13 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p)
 
        cfs_rq_of(pse)->next = pse;
 
+       /*
+        * We can come here with TIF_NEED_RESCHED already set from new task
+        * wake up path.
+        */
+       if (test_tsk_need_resched(curr))
+               return;
+
        /*
         * Batch tasks do not preempt (their preemption is driven by
         * the tick):
@@ -1360,33 +1270,15 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p)
        if (!sched_feat(WAKEUP_PREEMPT))
                return;
 
-       /*
-        * preemption test can be made between sibling entities who are in the
-        * same cfs_rq i.e who have a common parent. Walk up the hierarchy of
-        * both tasks until we find their ancestors who are siblings of common
-        * parent.
-        */
-
-       /* First walk up until both entities are at same depth */
-       se_depth = depth_se(se);
-       pse_depth = depth_se(pse);
-
-       while (se_depth > pse_depth) {
-               se_depth--;
-               se = parent_entity(se);
-       }
-
-       while (pse_depth > se_depth) {
-               pse_depth--;
-               pse = parent_entity(pse);
-       }
-
-       while (!is_same_group(se, pse)) {
-               se = parent_entity(se);
-               pse = parent_entity(pse);
+       if (sched_feat(WAKEUP_OVERLAP) && (sync ||
+                       (se->avg_overlap < sysctl_sched_migration_cost &&
+                        pse->avg_overlap < sysctl_sched_migration_cost))) {
+               resched_task(curr);
+               return;
        }
 
-       if (wakeup_preempt_entity(se, pse) == 1)
+       delta_exec = se->sum_exec_runtime - se->prev_sum_exec_runtime;
+       if (delta_exec > wakeup_gran(pse))
                resched_task(curr);
 }
 
@@ -1445,19 +1337,9 @@ __load_balance_iterator(struct cfs_rq *cfs_rq, struct list_head *next)
        if (next == &cfs_rq->tasks)
                return NULL;
 
-       /* Skip over entities that are not tasks */
-       do {
-               se = list_entry(next, struct sched_entity, group_node);
-               next = next->next;
-       } while (next != &cfs_rq->tasks && !entity_is_task(se));
-
-       if (next == &cfs_rq->tasks)
-               return NULL;
-
-       cfs_rq->balance_iterator = next;
-
-       if (entity_is_task(se))
-               p = task_of(se);
+       se = list_entry(next, struct sched_entity, group_node);
+       p = task_of(se);
+       cfs_rq->balance_iterator = next->next;
 
        return p;
 }
@@ -1507,7 +1389,7 @@ load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest,
        rcu_read_lock();
        update_h_load(busiest_cpu);
 
-       list_for_each_entry(tg, &task_groups, list) {
+       list_for_each_entry_rcu(tg, &task_groups, list) {
                struct cfs_rq *busiest_cfs_rq = tg->cfs_rq[busiest_cpu];
                unsigned long busiest_h_load = busiest_cfs_rq->h_load;
                unsigned long busiest_weight = busiest_cfs_rq->load.weight;
@@ -1620,10 +1502,10 @@ static void task_new_fair(struct rq *rq, struct task_struct *p)
                 * 'current' within the tree based on its new key value.
                 */
                swap(curr->vruntime, se->vruntime);
+               resched_task(rq->curr);
        }
 
        enqueue_task_fair(rq, p, 0);
-       resched_task(rq->curr);
 }
 
 /*
@@ -1642,7 +1524,7 @@ static void prio_changed_fair(struct rq *rq, struct task_struct *p,
                if (p->prio > oldprio)
                        resched_task(rq->curr);
        } else
-               check_preempt_curr(rq, p);
+               check_preempt_curr(rq, p, 0);
 }
 
 /*
@@ -1659,7 +1541,7 @@ static void switched_to_fair(struct rq *rq, struct task_struct *p,
        if (running)
                resched_task(rq->curr);
        else
-               check_preempt_curr(rq, p);
+               check_preempt_curr(rq, p, 0);
 }
 
 /* Account for a task changing its policy or group.
index 9353ca78154e880c786376108d2ef1be4335cde4..7c9e8f4a049f6c6ec6fb935de7d766b2135e8782 100644 (file)
@@ -11,3 +11,4 @@ SCHED_FEAT(ASYM_GRAN, 1)
 SCHED_FEAT(LB_BIAS, 1)
 SCHED_FEAT(LB_WAKEUP_UPDATE, 1)
 SCHED_FEAT(ASYM_EFF_LOAD, 1)
+SCHED_FEAT(WAKEUP_OVERLAP, 0)
index 3a4f92dbbe6609b786da0add62f2306e991b791f..dec4ccabe2f5c8af51566dcc323ce52858ff8764 100644 (file)
@@ -14,7 +14,7 @@ static int select_task_rq_idle(struct task_struct *p, int sync)
 /*
  * Idle tasks are unconditionally rescheduled:
  */
-static void check_preempt_curr_idle(struct rq *rq, struct task_struct *p)
+static void check_preempt_curr_idle(struct rq *rq, struct task_struct *p, int sync)
 {
        resched_task(rq->idle);
 }
@@ -76,7 +76,7 @@ static void switched_to_idle(struct rq *rq, struct task_struct *p,
        if (running)
                resched_task(rq->curr);
        else
-               check_preempt_curr(rq, p);
+               check_preempt_curr(rq, p, 0);
 }
 
 static void prio_changed_idle(struct rq *rq, struct task_struct *p,
@@ -93,7 +93,7 @@ static void prio_changed_idle(struct rq *rq, struct task_struct *p,
                if (p->prio > oldprio)
                        resched_task(rq->curr);
        } else
-               check_preempt_curr(rq, p);
+               check_preempt_curr(rq, p, 0);
 }
 
 /*
index 1113157b20581b07cbcdf325d4d3428cdd7cd288..cdf5740ab03e8133c0a2b7713d6c77d2be1f07bf 100644 (file)
@@ -102,12 +102,12 @@ static void dequeue_rt_entity(struct sched_rt_entity *rt_se);
 
 static void sched_rt_rq_enqueue(struct rt_rq *rt_rq)
 {
+       struct task_struct *curr = rq_of_rt_rq(rt_rq)->curr;
        struct sched_rt_entity *rt_se = rt_rq->rt_se;
 
-       if (rt_se && !on_rt_rq(rt_se) && rt_rq->rt_nr_running) {
-               struct task_struct *curr = rq_of_rt_rq(rt_rq)->curr;
-
-               enqueue_rt_entity(rt_se);
+       if (rt_rq->rt_nr_running) {
+               if (rt_se && !on_rt_rq(rt_se))
+                       enqueue_rt_entity(rt_se);
                if (rt_rq->highest_prio < curr->prio)
                        resched_task(curr);
        }
@@ -231,6 +231,9 @@ static inline struct rt_bandwidth *sched_rt_bandwidth(struct rt_rq *rt_rq)
 #endif /* CONFIG_RT_GROUP_SCHED */
 
 #ifdef CONFIG_SMP
+/*
+ * We ran out of runtime, see if we can borrow some from our neighbours.
+ */
 static int do_balance_runtime(struct rt_rq *rt_rq)
 {
        struct rt_bandwidth *rt_b = sched_rt_bandwidth(rt_rq);
@@ -250,9 +253,18 @@ static int do_balance_runtime(struct rt_rq *rt_rq)
                        continue;
 
                spin_lock(&iter->rt_runtime_lock);
+               /*
+                * Either all rqs have inf runtime and there's nothing to steal
+                * or __disable_runtime() below sets a specific rq to inf to
+                * indicate its been disabled and disalow stealing.
+                */
                if (iter->rt_runtime == RUNTIME_INF)
                        goto next;
 
+               /*
+                * From runqueues with spare time, take 1/n part of their
+                * spare time, but no more than our period.
+                */
                diff = iter->rt_runtime - iter->rt_time;
                if (diff > 0) {
                        diff = div_u64((u64)diff, weight);
@@ -274,6 +286,9 @@ next:
        return more;
 }
 
+/*
+ * Ensure this RQ takes back all the runtime it lend to its neighbours.
+ */
 static void __disable_runtime(struct rq *rq)
 {
        struct root_domain *rd = rq->rd;
@@ -289,17 +304,33 @@ static void __disable_runtime(struct rq *rq)
 
                spin_lock(&rt_b->rt_runtime_lock);
                spin_lock(&rt_rq->rt_runtime_lock);
+               /*
+                * Either we're all inf and nobody needs to borrow, or we're
+                * already disabled and thus have nothing to do, or we have
+                * exactly the right amount of runtime to take out.
+                */
                if (rt_rq->rt_runtime == RUNTIME_INF ||
                                rt_rq->rt_runtime == rt_b->rt_runtime)
                        goto balanced;
                spin_unlock(&rt_rq->rt_runtime_lock);
 
+               /*
+                * Calculate the difference between what we started out with
+                * and what we current have, that's the amount of runtime
+                * we lend and now have to reclaim.
+                */
                want = rt_b->rt_runtime - rt_rq->rt_runtime;
 
+               /*
+                * Greedy reclaim, take back as much as we can.
+                */
                for_each_cpu_mask(i, rd->span) {
                        struct rt_rq *iter = sched_rt_period_rt_rq(rt_b, i);
                        s64 diff;
 
+                       /*
+                        * Can't reclaim from ourselves or disabled runqueues.
+                        */
                        if (iter == rt_rq || iter->rt_runtime == RUNTIME_INF)
                                continue;
 
@@ -319,8 +350,16 @@ static void __disable_runtime(struct rq *rq)
                }
 
                spin_lock(&rt_rq->rt_runtime_lock);
+               /*
+                * We cannot be left wanting - that would mean some runtime
+                * leaked out of the system.
+                */
                BUG_ON(want);
 balanced:
+               /*
+                * Disable all the borrow logic by pretending we have inf
+                * runtime - in which case borrowing doesn't make sense.
+                */
                rt_rq->rt_runtime = RUNTIME_INF;
                spin_unlock(&rt_rq->rt_runtime_lock);
                spin_unlock(&rt_b->rt_runtime_lock);
@@ -343,6 +382,9 @@ static void __enable_runtime(struct rq *rq)
        if (unlikely(!scheduler_running))
                return;
 
+       /*
+        * Reset each runqueue's bandwidth settings
+        */
        for_each_leaf_rt_rq(rt_rq, rq) {
                struct rt_bandwidth *rt_b = sched_rt_bandwidth(rt_rq);
 
@@ -389,7 +431,7 @@ static int do_sched_rt_period_timer(struct rt_bandwidth *rt_b, int overrun)
        int i, idle = 1;
        cpumask_t span;
 
-       if (rt_b->rt_runtime == RUNTIME_INF)
+       if (!rt_bandwidth_enabled() || rt_b->rt_runtime == RUNTIME_INF)
                return 1;
 
        span = sched_rt_period_mask();
@@ -487,6 +529,9 @@ static void update_curr_rt(struct rq *rq)
        curr->se.exec_start = rq->clock;
        cpuacct_charge(curr, delta_exec);
 
+       if (!rt_bandwidth_enabled())
+               return;
+
        for_each_sched_rt_entity(rt_se) {
                rt_rq = rt_rq_of_se(rt_se);
 
@@ -784,7 +829,7 @@ static void check_preempt_equal_prio(struct rq *rq, struct task_struct *p)
 /*
  * Preempt the current task with a newly woken task if needed:
  */
-static void check_preempt_curr_rt(struct rq *rq, struct task_struct *p)
+static void check_preempt_curr_rt(struct rq *rq, struct task_struct *p, int sync)
 {
        if (p->prio < rq->curr->prio) {
                resched_task(rq->curr);
index 865ecf57a09604cc1307407cc99f90c1cecc5309..39d6159fae430cf60811839f4e2dbd20aadb9e4a 100644 (file)
@@ -169,7 +169,7 @@ static ssize_t cpu_rt_runtime_show(struct kobject *kobj,
 {
        struct user_struct *up = container_of(kobj, struct user_struct, kobj);
 
-       return sprintf(buf, "%lu\n", sched_group_rt_runtime(up->tg));
+       return sprintf(buf, "%ld\n", sched_group_rt_runtime(up->tg));
 }
 
 static ssize_t cpu_rt_runtime_store(struct kobject *kobj,
@@ -180,7 +180,7 @@ static ssize_t cpu_rt_runtime_store(struct kobject *kobj,
        unsigned long rt_runtime;
        int rc;
 
-       sscanf(buf, "%lu", &rt_runtime);
+       sscanf(buf, "%ld", &rt_runtime);
 
        rc = sched_group_set_rt_runtime(up->tg, rt_runtime);
 
index 9fee969dd60e1b65e0e1306f4c2ff3955b9a34c9..ce697e0b319ea08e8b8127197dd87becd9f0ef99 100644 (file)
@@ -637,6 +637,28 @@ config BACKTRACE_SELF_TEST
 
          Say N if you are unsure.
 
+config DEBUG_BLOCK_EXT_DEVT
+        bool "Force extended block device numbers and spread them"
+       depends on DEBUG_KERNEL
+       depends on BLOCK
+       default n
+       help
+         Conventionally, block device numbers are allocated from
+         predetermined contiguous area.  However, extended block area
+         may introduce non-contiguous block device numbers.  This
+         option forces most block device numbers to be allocated from
+         the extended space and spreads them to discover kernel or
+         userland code paths which assume predetermined contiguous
+         device number allocation.
+
+         Note that turning on this debug option shuffles all the
+         device numbers for all IDE and SCSI devices including libata
+         ones, so root partition specified using device number
+         directly (via rdev or root=MAJ:MIN) won't work anymore.
+         Textual device names (root=/dev/sdXn) will continue to work.
+
+         Say N if you are unsure.
+
 config LKDTM
        tristate "Linux Kernel Dump Test Tool Module"
        depends on DEBUG_KERNEL
@@ -674,10 +696,21 @@ config FAIL_PAGE_ALLOC
 
 config FAIL_MAKE_REQUEST
        bool "Fault-injection capability for disk IO"
-       depends on FAULT_INJECTION
+       depends on FAULT_INJECTION && BLOCK
        help
          Provide fault-injection capability for disk IO.
 
+config FAIL_IO_TIMEOUT
+       bool "Faul-injection capability for faking disk interrupts"
+       depends on FAULT_INJECTION && BLOCK
+       help
+         Provide fault-injection capability on end IO handling. This
+         will make the block layer "forget" an interrupt as configured,
+         thus exercising the error handling.
+
+         Only works with drivers that use the generic timeout handling,
+         for others it wont do anything.
+
 config FAULT_INJECTION_DEBUG_FS
        bool "Debugfs entries for fault-injection capabilities"
        depends on FAULT_INJECTION && SYSFS && DEBUG_FS
index 3b1f94bbe9de7415903c716753c0f96899c49938..44001af76a7dfc4f44216fa25959291633df36e7 100644 (file)
@@ -19,7 +19,8 @@ lib-$(CONFIG_SMP) += cpumask.o
 lib-y  += kobject.o kref.o klist.o
 
 obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \
-        bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o
+        bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \
+        string_helpers.o
 
 ifeq ($(CONFIG_DEBUG_KOBJECT),y)
 CFLAGS_kobject.o += -DDEBUG
index cca37f96faa22b5cbe73de502da86cd94f61997f..bbdd3015c2c787430acfb64f1802919619da6399 100644 (file)
 #include <linux/klist.h>
 #include <linux/module.h>
 
+/*
+ * Use the lowest bit of n_klist to mark deleted nodes and exclude
+ * dead ones from iteration.
+ */
+#define KNODE_DEAD             1LU
+#define KNODE_KLIST_MASK       ~KNODE_DEAD
+
+static struct klist *knode_klist(struct klist_node *knode)
+{
+       return (struct klist *)
+               ((unsigned long)knode->n_klist & KNODE_KLIST_MASK);
+}
+
+static bool knode_dead(struct klist_node *knode)
+{
+       return (unsigned long)knode->n_klist & KNODE_DEAD;
+}
+
+static void knode_set_klist(struct klist_node *knode, struct klist *klist)
+{
+       knode->n_klist = klist;
+       /* no knode deserves to start its life dead */
+       WARN_ON(knode_dead(knode));
+}
+
+static void knode_kill(struct klist_node *knode)
+{
+       /* and no knode should die twice ever either, see we're very humane */
+       WARN_ON(knode_dead(knode));
+       *(unsigned long *)&knode->n_klist |= KNODE_DEAD;
+}
 
 /**
  * klist_init - Initialize a klist structure.
@@ -79,7 +110,7 @@ static void klist_node_init(struct klist *k, struct klist_node *n)
        INIT_LIST_HEAD(&n->n_node);
        init_completion(&n->n_removed);
        kref_init(&n->n_ref);
-       n->n_klist = k;
+       knode_set_klist(n, k);
        if (k->get)
                k->get(n);
 }
@@ -115,7 +146,7 @@ EXPORT_SYMBOL_GPL(klist_add_tail);
  */
 void klist_add_after(struct klist_node *n, struct klist_node *pos)
 {
-       struct klist *k = pos->n_klist;
+       struct klist *k = knode_klist(pos);
 
        klist_node_init(k, n);
        spin_lock(&k->k_lock);
@@ -131,7 +162,7 @@ EXPORT_SYMBOL_GPL(klist_add_after);
  */
 void klist_add_before(struct klist_node *n, struct klist_node *pos)
 {
-       struct klist *k = pos->n_klist;
+       struct klist *k = knode_klist(pos);
 
        klist_node_init(k, n);
        spin_lock(&k->k_lock);
@@ -144,9 +175,10 @@ static void klist_release(struct kref *kref)
 {
        struct klist_node *n = container_of(kref, struct klist_node, n_ref);
 
+       WARN_ON(!knode_dead(n));
        list_del(&n->n_node);
        complete(&n->n_removed);
-       n->n_klist = NULL;
+       knode_set_klist(n, NULL);
 }
 
 static int klist_dec_and_del(struct klist_node *n)
@@ -154,22 +186,29 @@ static int klist_dec_and_del(struct klist_node *n)
        return kref_put(&n->n_ref, klist_release);
 }
 
-/**
- * klist_del - Decrement the reference count of node and try to remove.
- * @n: node we're deleting.
- */
-void klist_del(struct klist_node *n)
+static void klist_put(struct klist_node *n, bool kill)
 {
-       struct klist *k = n->n_klist;
+       struct klist *k = knode_klist(n);
        void (*put)(struct klist_node *) = k->put;
 
        spin_lock(&k->k_lock);
+       if (kill)
+               knode_kill(n);
        if (!klist_dec_and_del(n))
                put = NULL;
        spin_unlock(&k->k_lock);
        if (put)
                put(n);
 }
+
+/**
+ * klist_del - Decrement the reference count of node and try to remove.
+ * @n: node we're deleting.
+ */
+void klist_del(struct klist_node *n)
+{
+       klist_put(n, true);
+}
 EXPORT_SYMBOL_GPL(klist_del);
 
 /**
@@ -206,7 +245,6 @@ void klist_iter_init_node(struct klist *k, struct klist_iter *i,
                          struct klist_node *n)
 {
        i->i_klist = k;
-       i->i_head = &k->k_list;
        i->i_cur = n;
        if (n)
                kref_get(&n->n_ref);
@@ -237,7 +275,7 @@ EXPORT_SYMBOL_GPL(klist_iter_init);
 void klist_iter_exit(struct klist_iter *i)
 {
        if (i->i_cur) {
-               klist_del(i->i_cur);
+               klist_put(i->i_cur, false);
                i->i_cur = NULL;
        }
 }
@@ -258,27 +296,33 @@ static struct klist_node *to_klist_node(struct list_head *n)
  */
 struct klist_node *klist_next(struct klist_iter *i)
 {
-       struct list_head *next;
-       struct klist_node *lnode = i->i_cur;
-       struct klist_node *knode = NULL;
        void (*put)(struct klist_node *) = i->i_klist->put;
+       struct klist_node *last = i->i_cur;
+       struct klist_node *next;
 
        spin_lock(&i->i_klist->k_lock);
-       if (lnode) {
-               next = lnode->n_node.next;
-               if (!klist_dec_and_del(lnode))
+
+       if (last) {
+               next = to_klist_node(last->n_node.next);
+               if (!klist_dec_and_del(last))
                        put = NULL;
        } else
-               next = i->i_head->next;
+               next = to_klist_node(i->i_klist->k_list.next);
 
-       if (next != i->i_head) {
-               knode = to_klist_node(next);
-               kref_get(&knode->n_ref);
+       i->i_cur = NULL;
+       while (next != to_klist_node(&i->i_klist->k_list)) {
+               if (likely(!knode_dead(next))) {
+                       kref_get(&next->n_ref);
+                       i->i_cur = next;
+                       break;
+               }
+               next = to_klist_node(next->n_node.next);
        }
-       i->i_cur = knode;
+
        spin_unlock(&i->i_klist->k_lock);
-       if (put && lnode)
-               put(lnode);
-       return knode;
+
+       if (put && last)
+               put(last);
+       return i->i_cur;
 }
 EXPORT_SYMBOL_GPL(klist_next);
diff --git a/lib/string_helpers.c b/lib/string_helpers.c
new file mode 100644 (file)
index 0000000..8347925
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Helpers for formatting and printing strings
+ *
+ * Copyright 31 August 2008 James Bottomley
+ */
+#include <linux/kernel.h>
+#include <linux/math64.h>
+#include <linux/module.h>
+#include <linux/string_helpers.h>
+
+/**
+ * string_get_size - get the size in the specified units
+ * @size:      The size to be converted
+ * @units:     units to use (powers of 1000 or 1024)
+ * @buf:       buffer to format to
+ * @len:       length of buffer
+ *
+ * This function returns a string formatted to 3 significant figures
+ * giving the size in the required units.  Returns 0 on success or
+ * error on failure.  @buf is always zero terminated.
+ *
+ */
+int string_get_size(u64 size, const enum string_size_units units,
+                   char *buf, int len)
+{
+       const char *units_10[] = { "B", "KB", "MB", "GB", "TB", "PB",
+                                  "EB", "ZB", "YB", NULL};
+       const char *units_2[] = {"B", "KiB", "MiB", "GiB", "TiB", "PiB",
+                                "EiB", "ZiB", "YiB", NULL };
+       const char **units_str[] = {
+               [STRING_UNITS_10] =  units_10,
+               [STRING_UNITS_2] = units_2,
+       };
+       const int divisor[] = {
+               [STRING_UNITS_10] = 1000,
+               [STRING_UNITS_2] = 1024,
+       };
+       int i, j;
+       u64 remainder = 0, sf_cap;
+       char tmp[8];
+
+       tmp[0] = '\0';
+
+       for (i = 0; size > divisor[units] && units_str[units][i]; i++)
+               remainder = do_div(size, divisor[units]);
+
+       sf_cap = size;
+       for (j = 0; sf_cap*10 < 1000; j++)
+               sf_cap *= 10;
+
+       if (j) {
+               remainder *= 1000;
+               do_div(remainder, divisor[units]);
+               snprintf(tmp, sizeof(tmp), ".%03lld",
+                        (unsigned long long)remainder);
+               tmp[j+1] = '\0';
+       }
+
+       snprintf(buf, len, "%lld%s%s", (unsigned long long)size,
+                tmp, units_str[units][i]);
+
+       return 0;
+}
+EXPORT_SYMBOL(string_get_size);
index b6d2d0f1019b3975640a5b0388825b44112be7de..06722c4030584382478d7c447ad35f96fe856dd6 100644 (file)
@@ -267,7 +267,7 @@ void blk_queue_bounce(struct request_queue *q, struct bio **bio_orig)
        /*
         * Data-less bio, nothing to bounce
         */
-       if (bio_empty_barrier(*bio_orig))
+       if (!bio_has_data(*bio_orig))
                return;
 
        /*
index 62b679dc660fb9244a745142c79186000793343f..cb675d1267914dc263100b9c4a9ea5eb20fefa48 100644 (file)
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -514,9 +514,11 @@ size_t ksize(const void *block)
                return 0;
 
        sp = (struct slob_page *)virt_to_page(block);
-       if (slob_page(sp))
-               return (((slob_t *)block - 1)->units - 1) * SLOB_UNIT;
-       else
+       if (slob_page(sp)) {
+               int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
+               unsigned int *m = (unsigned int *)(block - align);
+               return SLOB_UNITS(*m) * SLOB_UNIT;
+       } else
                return sp->page.private;
 }
 
index 1c73c5aea66b06bcecff315356abcecc2a79522f..aafdf064feefdf49bc98d66c72199907e30ca921 100644 (file)
@@ -20,6 +20,7 @@ hostprogs-y += unifdef
 
 subdir-$(CONFIG_MODVERSIONS) += genksyms
 subdir-y                     += mod
+subdir-$(CONFIG_SECURITY_SELINUX) += selinux
 
 # Let clean descend into subdirs
-subdir-        += basic kconfig package
+subdir-        += basic kconfig package selinux
diff --git a/scripts/selinux/Makefile b/scripts/selinux/Makefile
new file mode 100644 (file)
index 0000000..ca4b1ec
--- /dev/null
@@ -0,0 +1,2 @@
+subdir-y := mdp
+subdir-        += mdp
diff --git a/scripts/selinux/README b/scripts/selinux/README
new file mode 100644 (file)
index 0000000..a936315
--- /dev/null
@@ -0,0 +1,2 @@
+Please see Documentation/SELinux.txt for information on
+installing a dummy SELinux policy.
diff --git a/scripts/selinux/install_policy.sh b/scripts/selinux/install_policy.sh
new file mode 100644 (file)
index 0000000..7b9ccf6
--- /dev/null
@@ -0,0 +1,69 @@
+#!/bin/sh
+if [ `id -u` -ne 0 ]; then
+       echo "$0: must be root to install the selinux policy"
+       exit 1
+fi
+SF=`which setfiles`
+if [ $? -eq 1 ]; then
+       if [ -f /sbin/setfiles ]; then
+               SF="/usr/setfiles"
+       else
+               echo "no selinux tools installed: setfiles"
+               exit 1
+       fi
+fi
+
+cd mdp
+
+CP=`which checkpolicy`
+VERS=`$CP -V | awk '{print $1}'`
+
+./mdp policy.conf file_contexts
+$CP -o policy.$VERS policy.conf
+
+mkdir -p /etc/selinux/dummy/policy
+mkdir -p /etc/selinux/dummy/contexts/files
+
+cp file_contexts /etc/selinux/dummy/contexts/files
+cp dbus_contexts /etc/selinux/dummy/contexts
+cp policy.$VERS /etc/selinux/dummy/policy
+FC_FILE=/etc/selinux/dummy/contexts/files/file_contexts
+
+if [ ! -d /etc/selinux ]; then
+       mkdir -p /etc/selinux
+fi
+if [ ! -f /etc/selinux/config ]; then
+       cat > /etc/selinux/config << EOF
+SELINUX=enforcing
+SELINUXTYPE=dummy
+EOF
+else
+       TYPE=`cat /etc/selinux/config | grep "^SELINUXTYPE" | tail -1 | awk -F= '{ print $2 '}`
+       if [ "eq$TYPE" != "eqdummy" ]; then
+               selinuxenabled
+               if [ $? -eq 0 ]; then
+                       echo "SELinux already enabled with a non-dummy policy."
+                       echo "Exiting.  Please install policy by hand if that"
+                       echo "is what you REALLY want."
+                       exit 1
+               fi
+               mv /etc/selinux/config /etc/selinux/config.mdpbak
+               grep -v "^SELINUXTYPE" /etc/selinux/config.mdpbak >> /etc/selinux/config
+               echo "SELINUXTYPE=dummy" >> /etc/selinux/config
+       fi
+fi
+
+cd /etc/selinux/dummy/contexts/files
+$SF file_contexts /
+
+mounts=`cat /proc/$$/mounts | egrep "ext2|ext3|xfs|jfs|ext4|ext4dev|gfs2" | awk '{ print $2 '}`
+$SF file_contexts $mounts
+
+
+dodev=`cat /proc/$$/mounts | grep "/dev "`
+if [ "eq$dodev" != "eq" ]; then
+       mount --move /dev /mnt
+       $SF file_contexts /dev
+       mount --move /mnt /dev
+fi
+
diff --git a/scripts/selinux/mdp/.gitignore b/scripts/selinux/mdp/.gitignore
new file mode 100644 (file)
index 0000000..654546d
--- /dev/null
@@ -0,0 +1,2 @@
+# Generated file
+mdp
diff --git a/scripts/selinux/mdp/Makefile b/scripts/selinux/mdp/Makefile
new file mode 100644 (file)
index 0000000..eb365b3
--- /dev/null
@@ -0,0 +1,5 @@
+hostprogs-y    := mdp
+HOST_EXTRACFLAGS += -Isecurity/selinux/include
+
+always         := $(hostprogs-y)
+clean-files    := $(hostprogs-y) policy.* file_contexts
diff --git a/scripts/selinux/mdp/dbus_contexts b/scripts/selinux/mdp/dbus_contexts
new file mode 100644 (file)
index 0000000..116e684
--- /dev/null
@@ -0,0 +1,6 @@
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+  <selinux>
+  </selinux>
+</busconfig>
diff --git a/scripts/selinux/mdp/mdp.c b/scripts/selinux/mdp/mdp.c
new file mode 100644 (file)
index 0000000..ca757d4
--- /dev/null
@@ -0,0 +1,242 @@
+/*
+ *
+ * mdp - make dummy policy
+ *
+ * When pointed at a kernel tree, builds a dummy policy for that kernel
+ * with exactly one type with full rights to itself.
+ *
+ * This program 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 program 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 program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2006
+ *
+ * Authors: Serge E. Hallyn <serue@us.ibm.com>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "flask.h"
+
+void usage(char *name)
+{
+       printf("usage: %s [-m] policy_file context_file\n", name);
+       exit(1);
+}
+
+void find_common_name(char *cname, char *dest, int len)
+{
+       char *start, *end;
+
+       start = strchr(cname, '_')+1;
+       end = strchr(start, '_');
+       if (!start || !end || start-cname > len || end-start > len) {
+               printf("Error with commons defines\n");
+               exit(1);
+       }
+       strncpy(dest, start, end-start);
+       dest[end-start] = '\0';
+}
+
+#define S_(x) x,
+static char *classlist[] = {
+#include "class_to_string.h"
+       NULL
+};
+#undef S_
+
+#include "initial_sid_to_string.h"
+
+#define TB_(x) char *x[] = {
+#define TE_(x) NULL };
+#define S_(x) x,
+#include "common_perm_to_string.h"
+#undef TB_
+#undef TE_
+#undef S_
+
+struct common {
+       char *cname;
+       char **perms;
+};
+struct common common[] = {
+#define TB_(x) { #x, x },
+#define S_(x)
+#define TE_(x)
+#include "common_perm_to_string.h"
+#undef TB_
+#undef TE_
+#undef S_
+};
+
+#define S_(x, y, z) {x, #y},
+struct av_inherit {
+       int class;
+       char *common;
+};
+struct av_inherit av_inherit[] = {
+#include "av_inherit.h"
+};
+#undef S_
+
+#include "av_permissions.h"
+#define S_(x, y, z) {x, y, z},
+struct av_perms {
+       int class;
+       int perm_i;
+       char *perm_s;
+};
+struct av_perms av_perms[] = {
+#include "av_perm_to_string.h"
+};
+#undef S_
+
+int main(int argc, char *argv[])
+{
+       int i, j, mls = 0;
+       char **arg, *polout, *ctxout;
+       int classlist_len, initial_sid_to_string_len;
+       FILE *fout;
+
+       if (argc < 3)
+               usage(argv[0]);
+       arg = argv+1;
+       if (argc==4 && strcmp(argv[1], "-m") == 0) {
+               mls = 1;
+               arg++;
+       }
+       polout = *arg++;
+       ctxout = *arg;
+
+       fout = fopen(polout, "w");
+       if (!fout) {
+               printf("Could not open %s for writing\n", polout);
+               usage(argv[0]);
+       }
+
+       classlist_len = sizeof(classlist) / sizeof(char *);
+       /* print out the classes */
+       for (i=1; i < classlist_len; i++) {
+               if(classlist[i])
+                       fprintf(fout, "class %s\n", classlist[i]);
+               else
+                       fprintf(fout, "class user%d\n", i);
+       }
+       fprintf(fout, "\n");
+
+       initial_sid_to_string_len = sizeof(initial_sid_to_string) / sizeof (char *);
+       /* print out the sids */
+       for (i=1; i < initial_sid_to_string_len; i++)
+               fprintf(fout, "sid %s\n", initial_sid_to_string[i]);
+       fprintf(fout, "\n");
+
+       /* print out the commons */
+       for (i=0; i< sizeof(common)/sizeof(struct common); i++) {
+               char cname[101];
+               find_common_name(common[i].cname, cname, 100);
+               cname[100] = '\0';
+               fprintf(fout, "common %s\n{\n", cname);
+               for (j=0; common[i].perms[j]; j++)
+                       fprintf(fout, "\t%s\n", common[i].perms[j]);
+               fprintf(fout, "}\n\n");
+       }
+       fprintf(fout, "\n");
+
+       /* print out the class permissions */
+       for (i=1; i < classlist_len; i++) {
+               if (classlist[i]) {
+                       int firstperm = -1, numperms = 0;
+
+                       fprintf(fout, "class %s\n", classlist[i]);
+                       /* does it inherit from a common? */
+                       for (j=0; j < sizeof(av_inherit)/sizeof(struct av_inherit); j++)
+                               if (av_inherit[j].class == i)
+                                       fprintf(fout, "inherits %s\n", av_inherit[j].common);
+
+                       for (j=0; j < sizeof(av_perms)/sizeof(struct av_perms); j++) {
+                               if (av_perms[j].class == i) {
+                                       if (firstperm == -1)
+                                               firstperm = j;
+                                       numperms++;
+                               }
+                       }
+                       if (!numperms) {
+                               fprintf(fout, "\n");
+                               continue;
+                       }
+
+                       fprintf(fout, "{\n");
+                       /* print out the av_perms */
+                       for (j=0; j < numperms; j++) {
+                               fprintf(fout, "\t%s\n", av_perms[firstperm+j].perm_s);
+                       }
+                       fprintf(fout, "}\n\n");
+               }
+       }
+       fprintf(fout, "\n");
+
+       /* NOW PRINT OUT MLS STUFF */
+       if (mls) {
+               printf("MLS not yet implemented\n");
+               exit(1);
+       }
+
+       /* types, roles, and allows */
+       fprintf(fout, "type base_t;\n");
+       fprintf(fout, "role base_r types { base_t };\n");
+       for (i=1; i < classlist_len; i++) {
+               if (classlist[i])
+                       fprintf(fout, "allow base_t base_t:%s *;\n", classlist[i]);
+               else
+                       fprintf(fout, "allow base_t base_t:user%d *;\n", i);
+       }
+       fprintf(fout, "user user_u roles { base_r };\n");
+       fprintf(fout, "\n");
+
+       /* default sids */
+       for (i=1; i < initial_sid_to_string_len; i++)
+               fprintf(fout, "sid %s user_u:base_r:base_t\n", initial_sid_to_string[i]);
+       fprintf(fout, "\n");
+
+
+       fprintf(fout, "fs_use_xattr ext2 user_u:base_r:base_t;\n");
+       fprintf(fout, "fs_use_xattr ext3 user_u:base_r:base_t;\n");
+       fprintf(fout, "fs_use_xattr jfs user_u:base_r:base_t;\n");
+       fprintf(fout, "fs_use_xattr xfs user_u:base_r:base_t;\n");
+       fprintf(fout, "fs_use_xattr reiserfs user_u:base_r:base_t;\n");
+
+       fprintf(fout, "fs_use_task pipefs user_u:base_r:base_t;\n");
+       fprintf(fout, "fs_use_task sockfs user_u:base_r:base_t;\n");
+
+       fprintf(fout, "fs_use_trans devpts user_u:base_r:base_t;\n");
+       fprintf(fout, "fs_use_trans tmpfs user_u:base_r:base_t;\n");
+       fprintf(fout, "fs_use_trans shm user_u:base_r:base_t;\n");
+
+       fprintf(fout, "genfscon proc / user_u:base_r:base_t\n");
+
+       fclose(fout);
+
+       fout = fopen(ctxout, "w");
+       if (!fout) {
+               printf("Wrote policy, but cannot open %s for writing\n", ctxout);
+               usage(argv[0]);
+       }
+       fprintf(fout, "/ user_u:base_r:base_t\n");
+       fprintf(fout, "/.* user_u:base_r:base_t\n");
+       fclose(fout);
+
+       return 0;
+}
index 559293922a479eabf188b70e963d5264f9032799..d9f47ce7e2076877064e50eb2e34fd0f9c9fbd2a 100644 (file)
@@ -51,6 +51,14 @@ config SECURITY
 
          If you are unsure how to answer this question, answer N.
 
+config SECURITYFS
+       bool "Enable the securityfs filesystem"
+       help
+         This will build the securityfs filesystem.  It is currently used by
+         the TPM bios character driver.  It is not used by SELinux or SMACK.
+
+         If you are unsure how to answer this question, answer N.
+
 config SECURITY_NETWORK
        bool "Socket and Networking Security Hooks"
        depends on SECURITY
index f65426099aa625be9aac60a1a009ea860956dbb7..c05c127fff9a795d9b3c21d7c1a510c6b7a5a4cc 100644 (file)
@@ -10,7 +10,8 @@ subdir-$(CONFIG_SECURITY_SMACK)               += smack
 obj-y          += commoncap.o
 
 # Object file lists
-obj-$(CONFIG_SECURITY)                 += security.o capability.o inode.o
+obj-$(CONFIG_SECURITY)                 += security.o capability.o
+obj-$(CONFIG_SECURITYFS)               += inode.o
 # Must precede capability.o in order to stack properly.
 obj-$(CONFIG_SECURITY_SELINUX)         += selinux/built-in.o
 obj-$(CONFIG_SECURITY_SMACK)           += smack/built-in.o
index e4c4b3fc0c04e49e553610a8bd4d433e55e9212a..399bfdb9e2da99c4ef81fdd8b0391b1f5571c371 100644 (file)
@@ -541,7 +541,7 @@ int cap_task_post_setuid (uid_t old_ruid, uid_t old_euid, uid_t old_suid,
  * yet with increased caps.
  * So we check for increased caps on the target process.
  */
-static inline int cap_safe_nice(struct task_struct *p)
+static int cap_safe_nice(struct task_struct *p)
 {
        if (!cap_issubset(p->cap_permitted, current->cap_permitted) &&
            !capable(CAP_SYS_NICE))
index acc6cf0d79001fa06d53c5b592fb4c90f5ea88a2..ca4958ebad8d30c7c4f8ce4bdf1b98309fe2e13e 100644 (file)
@@ -190,7 +190,7 @@ static int create_by_name(const char *name, mode_t mode,
  * @name: a pointer to a string containing the name of the file to create.
  * @mode: the permission that the file should have
  * @parent: a pointer to the parent dentry for this file.  This should be a
- *          directory dentry if set.  If this paramater is NULL, then the
+ *          directory dentry if set.  If this parameter is %NULL, then the
  *          file will be created in the root of the securityfs filesystem.
  * @data: a pointer to something that the caller will want to get to later
  *        on.  The inode.i_private pointer will point to this value on
@@ -199,18 +199,18 @@ static int create_by_name(const char *name, mode_t mode,
  *        this file.
  *
  * This is the basic "create a file" function for securityfs.  It allows for a
- * wide range of flexibility in createing a file, or a directory (if you
+ * wide range of flexibility in creating a file, or a directory (if you
  * want to create a directory, the securityfs_create_dir() function is
- * recommended to be used instead.)
+ * recommended to be used instead).
  *
- * This function will return a pointer to a dentry if it succeeds.  This
+ * This function returns a pointer to a dentry if it succeeds.  This
  * pointer must be passed to the securityfs_remove() function when the file is
  * to be removed (no automatic cleanup happens if your module is unloaded,
- * you are responsible here.)  If an error occurs, NULL will be returned.
+ * you are responsible here).  If an error occurs, %NULL is returned.
  *
- * If securityfs is not enabled in the kernel, the value -ENODEV will be
+ * If securityfs is not enabled in the kernel, the value %-ENODEV is
  * returned.  It is not wise to check for this value, but rather, check for
- * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
+ * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
  * code.
  */
 struct dentry *securityfs_create_file(const char *name, mode_t mode,
@@ -252,19 +252,19 @@ EXPORT_SYMBOL_GPL(securityfs_create_file);
  * @name: a pointer to a string containing the name of the directory to
  *        create.
  * @parent: a pointer to the parent dentry for this file.  This should be a
- *          directory dentry if set.  If this paramater is NULL, then the
+ *          directory dentry if set.  If this parameter is %NULL, then the
  *          directory will be created in the root of the securityfs filesystem.
  *
- * This function creates a directory in securityfs with the given name.
+ * This function creates a directory in securityfs with the given @name.
  *
- * This function will return a pointer to a dentry if it succeeds.  This
+ * This function returns a pointer to a dentry if it succeeds.  This
  * pointer must be passed to the securityfs_remove() function when the file is
  * to be removed (no automatic cleanup happens if your module is unloaded,
- * you are responsible here.)  If an error occurs, NULL will be returned.
+ * you are responsible here).  If an error occurs, %NULL will be returned.
  *
- * If securityfs is not enabled in the kernel, the value -ENODEV will be
+ * If securityfs is not enabled in the kernel, the value %-ENODEV is
  * returned.  It is not wise to check for this value, but rather, check for
- * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
+ * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
  * code.
  */
 struct dentry *securityfs_create_dir(const char *name, struct dentry *parent)
@@ -278,16 +278,15 @@ EXPORT_SYMBOL_GPL(securityfs_create_dir);
 /**
  * securityfs_remove - removes a file or directory from the securityfs filesystem
  *
- * @dentry: a pointer to a the dentry of the file or directory to be
- *          removed.
+ * @dentry: a pointer to a the dentry of the file or directory to be removed.
  *
  * This function removes a file or directory in securityfs that was previously
  * created with a call to another securityfs function (like
  * securityfs_create_file() or variants thereof.)
  *
  * This function is required to be called in order for the file to be
- * removed, no automatic cleanup of files will happen when a module is
- * removed, you are responsible here.
+ * removed. No automatic cleanup of files will happen when a module is
+ * removed; you are responsible here.
  */
 void securityfs_remove(struct dentry *dentry)
 {
index 3a4b4f55b33f373d5a85145d61e6de95cce4bf3c..255b08559b2b62e057d5fda7a8b4396b2bdbb065 100644 (file)
@@ -82,8 +82,8 @@ __setup("security=", choose_lsm);
  *
  * Return true if:
  *     -The passed LSM is the one chosen by user at boot time,
- *     -or user didsn't specify a specific LSM and we're the first to ask
- *      for registeration permissoin,
+ *     -or user didn't specify a specific LSM and we're the first to ask
+ *      for registration permission,
  *     -or the passed LSM is currently loaded.
  * Otherwise, return false.
  */
@@ -101,13 +101,13 @@ int __init security_module_enable(struct security_operations *ops)
  * register_security - registers a security framework with the kernel
  * @ops: a pointer to the struct security_options that is to be registered
  *
- * This function is to allow a security module to register itself with the
+ * This function allows a security module to register itself with the
  * kernel security subsystem.  Some rudimentary checking is done on the @ops
  * value passed to this function. You'll need to check first if your LSM
  * is allowed to register its @ops by calling security_module_enable(@ops).
  *
  * If there is already a security module registered with the kernel,
- * an error will be returned.  Otherwise 0 is returned on success.
+ * an error will be returned.  Otherwise %0 is returned on success.
  */
 int register_security(struct security_operations *ops)
 {
index a436d1cfa88b8ef68fec2de2addf3af4cc2e54e3..26301dd651d3a4722efde37d16855f3c622b71bc 100644 (file)
@@ -6,9 +6,6 @@ config SECURITY_SELINUX
        help
          This selects NSA Security-Enhanced Linux (SELinux).
          You will also need a policy configuration and a labeled filesystem.
-         You can obtain the policy compiler (checkpolicy), the utility for
-         labeling filesystems (setfiles), and an example policy configuration
-         from <http://www.nsa.gov/selinux/>.
          If you are unsure how to answer this question, answer N.
 
 config SECURITY_SELINUX_BOOTPARAM
index 114b4b4c97b23b9acdf25e92d1b250f78167457d..cb30c7e350b356c00a8d77dc5532ff20b6e5f62d 100644 (file)
@@ -136,7 +136,7 @@ static inline int avc_hash(u32 ssid, u32 tsid, u16 tclass)
  * @tclass: target security class
  * @av: access vector
  */
-static void avc_dump_av(struct audit_buffer *ab, u16 tclass, u32 av)
+void avc_dump_av(struct audit_buffer *ab, u16 tclass, u32 av)
 {
        const char **common_pts = NULL;
        u32 common_base = 0;
index 03fc6a81ae32bd783ddd96eca85f118a2ba79bd8..4a7374c12d9ca5a2b9c76c1101ecb42ee44b48af 100644 (file)
@@ -957,7 +957,8 @@ out_err:
        return rc;
 }
 
-void selinux_write_opts(struct seq_file *m, struct security_mnt_opts *opts)
+static void selinux_write_opts(struct seq_file *m,
+                              struct security_mnt_opts *opts)
 {
        int i;
        char *prefix;
@@ -1290,7 +1291,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
                /* Default to the fs superblock SID. */
                isec->sid = sbsec->sid;
 
-               if (sbsec->proc) {
+               if (sbsec->proc && !S_ISLNK(inode->i_mode)) {
                        struct proc_inode *proci = PROC_I(inode);
                        if (proci->pde) {
                                isec->sclass = inode_mode_to_security_class(inode->i_mode);
@@ -3548,38 +3549,44 @@ out:
 #endif /* IPV6 */
 
 static int selinux_parse_skb(struct sk_buff *skb, struct avc_audit_data *ad,
-                            char **addrp, int src, u8 *proto)
+                            char **_addrp, int src, u8 *proto)
 {
-       int ret = 0;
+       char *addrp;
+       int ret;
 
        switch (ad->u.net.family) {
        case PF_INET:
                ret = selinux_parse_skb_ipv4(skb, ad, proto);
-               if (ret || !addrp)
-                       break;
-               *addrp = (char *)(src ? &ad->u.net.v4info.saddr :
-                                       &ad->u.net.v4info.daddr);
-               break;
+               if (ret)
+                       goto parse_error;
+               addrp = (char *)(src ? &ad->u.net.v4info.saddr :
+                                      &ad->u.net.v4info.daddr);
+               goto okay;
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
        case PF_INET6:
                ret = selinux_parse_skb_ipv6(skb, ad, proto);
-               if (ret || !addrp)
-                       break;
-               *addrp = (char *)(src ? &ad->u.net.v6info.saddr :
-                                       &ad->u.net.v6info.daddr);
-               break;
+               if (ret)
+                       goto parse_error;
+               addrp = (char *)(src ? &ad->u.net.v6info.saddr :
+                                      &ad->u.net.v6info.daddr);
+               goto okay;
 #endif /* IPV6 */
        default:
-               break;
+               addrp = NULL;
+               goto okay;
        }
 
-       if (unlikely(ret))
-               printk(KERN_WARNING
-                      "SELinux: failure in selinux_parse_skb(),"
-                      " unable to parse packet\n");
-
+parse_error:
+       printk(KERN_WARNING
+              "SELinux: failure in selinux_parse_skb(),"
+              " unable to parse packet\n");
        return ret;
+
+okay:
+       if (_addrp)
+               *_addrp = addrp;
+       return 0;
 }
 
 /**
@@ -5219,8 +5226,12 @@ static int selinux_setprocattr(struct task_struct *p,
 
                if (sid == 0)
                        return -EINVAL;
-
-               /* Only allow single threaded processes to change context */
+               /*
+                * SELinux allows to change context in the following case only.
+                *  - Single threaded processes.
+                *  - Multi threaded processes intend to change its context into
+                *    more restricted domain (defined by TYPEBOUNDS statement).
+                */
                if (atomic_read(&p->mm->mm_users) != 1) {
                        struct task_struct *g, *t;
                        struct mm_struct *mm = p->mm;
@@ -5228,11 +5239,16 @@ static int selinux_setprocattr(struct task_struct *p,
                        do_each_thread(g, t) {
                                if (t->mm == mm && t != p) {
                                        read_unlock(&tasklist_lock);
-                                       return -EPERM;
+                                       error = security_bounded_transition(tsec->sid, sid);
+                                       if (!error)
+                                               goto boundary_ok;
+
+                                       return error;
                                }
                        } while_each_thread(g, t);
                        read_unlock(&tasklist_lock);
                }
+boundary_ok:
 
                /* Check permissions for the transition. */
                error = avc_has_perm(tsec->sid, sid, SECCLASS_PROCESS,
index 7b9769f5e775e1dcacd24292aa2ba43d60e38691..d12ff1a9c0aa5e383347af29f9f03fe96e626ed2 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/kdev_t.h>
 #include <linux/spinlock.h>
 #include <linux/init.h>
+#include <linux/audit.h>
 #include <linux/in6.h>
 #include <linux/path.h>
 #include <asm/system.h>
@@ -126,6 +127,9 @@ int avc_add_callback(int (*callback)(u32 event, u32 ssid, u32 tsid,
                     u32 events, u32 ssid, u32 tsid,
                     u16 tclass, u32 perms);
 
+/* Shows permission in human readable form */
+void avc_dump_av(struct audit_buffer *ab, u16 tclass, u32 av);
+
 /* Exported to selinuxfs */
 int avc_get_hash_stats(char *page);
 extern unsigned int avc_cache_threshold;
index 7c543003d653676f5d72a34ffd60d1f301b2d11a..72447370bc959f4551583d421993138dc9c513b2 100644 (file)
 #define POLICYDB_VERSION_RANGETRANS    21
 #define POLICYDB_VERSION_POLCAP                22
 #define POLICYDB_VERSION_PERMISSIVE    23
+#define POLICYDB_VERSION_BOUNDARY      24
 
 /* Range of policy versions we understand*/
 #define POLICYDB_VERSION_MIN   POLICYDB_VERSION_BASE
 #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
 #define POLICYDB_VERSION_MAX   CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
 #else
-#define POLICYDB_VERSION_MAX   POLICYDB_VERSION_PERMISSIVE
+#define POLICYDB_VERSION_MAX   POLICYDB_VERSION_BOUNDARY
 #endif
 
 #define CONTEXT_MNT    0x01
@@ -62,6 +63,16 @@ enum {
 extern int selinux_policycap_netpeer;
 extern int selinux_policycap_openperm;
 
+/*
+ * type_datum properties
+ * available at the kernel policy version >= POLICYDB_VERSION_BOUNDARY
+ */
+#define TYPEDATUM_PROPERTY_PRIMARY     0x0001
+#define TYPEDATUM_PROPERTY_ATTRIBUTE   0x0002
+
+/* limitation of boundary depth  */
+#define POLICYDB_BOUNDS_MAXDEPTH       4
+
 int security_load_policy(void *data, size_t len);
 
 int security_policycap_supported(unsigned int req_cap);
@@ -117,6 +128,8 @@ int security_node_sid(u16 domain, void *addr, u32 addrlen,
 int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
                                 u16 tclass);
 
+int security_bounded_transition(u32 oldsid, u32 newsid);
+
 int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid);
 
 int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type,
index a1be97f8beea0ac0aa0fa7519801128b6eb54b62..1215b8e47dba669a6d86519b342de621b2efbfd2 100644 (file)
@@ -98,7 +98,7 @@ struct avtab_node *
 avtab_insert_nonunique(struct avtab *h, struct avtab_key *key, struct avtab_datum *datum)
 {
        int hvalue;
-       struct avtab_node *prev, *cur, *newnode;
+       struct avtab_node *prev, *cur;
        u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
 
        if (!h || !h->htable)
@@ -122,9 +122,7 @@ avtab_insert_nonunique(struct avtab *h, struct avtab_key *key, struct avtab_datu
                    key->target_class < cur->key.target_class)
                        break;
        }
-       newnode = avtab_insert_node(h, hvalue, prev, cur, key, datum);
-
-       return newnode;
+       return avtab_insert_node(h, hvalue, prev, cur, key, datum);
 }
 
 struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key)
@@ -231,7 +229,7 @@ void avtab_destroy(struct avtab *h)
 
        for (i = 0; i < h->nslot; i++) {
                cur = h->htable[i];
-               while (cur != NULL) {
+               while (cur) {
                        temp = cur;
                        cur = cur->next;
                        kmem_cache_free(avtab_node_cachep, temp);
index fb4efe4f4bc8a5377192052d65242b683a87b438..4a4e35cac22bfc2a7426dd85e582ce113e07e843 100644 (file)
@@ -29,7 +29,7 @@ static int cond_evaluate_expr(struct policydb *p, struct cond_expr *expr)
        int s[COND_EXPR_MAXDEPTH];
        int sp = -1;
 
-       for (cur = expr; cur != NULL; cur = cur->next) {
+       for (cur = expr; cur; cur = cur->next) {
                switch (cur->expr_type) {
                case COND_BOOL:
                        if (sp == (COND_EXPR_MAXDEPTH - 1))
@@ -97,14 +97,14 @@ int evaluate_cond_node(struct policydb *p, struct cond_node *node)
                if (new_state == -1)
                        printk(KERN_ERR "SELinux: expression result was undefined - disabling all rules.\n");
                /* turn the rules on or off */
-               for (cur = node->true_list; cur != NULL; cur = cur->next) {
+               for (cur = node->true_list; cur; cur = cur->next) {
                        if (new_state <= 0)
                                cur->node->key.specified &= ~AVTAB_ENABLED;
                        else
                                cur->node->key.specified |= AVTAB_ENABLED;
                }
 
-               for (cur = node->false_list; cur != NULL; cur = cur->next) {
+               for (cur = node->false_list; cur; cur = cur->next) {
                        /* -1 or 1 */
                        if (new_state)
                                cur->node->key.specified &= ~AVTAB_ENABLED;
@@ -128,7 +128,7 @@ int cond_policydb_init(struct policydb *p)
 static void cond_av_list_destroy(struct cond_av_list *list)
 {
        struct cond_av_list *cur, *next;
-       for (cur = list; cur != NULL; cur = next) {
+       for (cur = list; cur; cur = next) {
                next = cur->next;
                /* the avtab_ptr_t node is destroy by the avtab */
                kfree(cur);
@@ -139,7 +139,7 @@ static void cond_node_destroy(struct cond_node *node)
 {
        struct cond_expr *cur_expr, *next_expr;
 
-       for (cur_expr = node->expr; cur_expr != NULL; cur_expr = next_expr) {
+       for (cur_expr = node->expr; cur_expr; cur_expr = next_expr) {
                next_expr = cur_expr->next;
                kfree(cur_expr);
        }
@@ -155,7 +155,7 @@ static void cond_list_destroy(struct cond_node *list)
        if (list == NULL)
                return;
 
-       for (cur = list; cur != NULL; cur = next) {
+       for (cur = list; cur; cur = next) {
                next = cur->next;
                cond_node_destroy(cur);
        }
@@ -239,7 +239,7 @@ int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp)
        rc = next_entry(key, fp, len);
        if (rc < 0)
                goto err;
-       key[len] = 0;
+       key[len] = '\0';
        if (hashtab_insert(h, key, booldatum))
                goto err;
 
@@ -291,7 +291,7 @@ static int cond_insertf(struct avtab *a, struct avtab_key *k, struct avtab_datum
                                        goto err;
                                }
                                found = 0;
-                               for (cur = other; cur != NULL; cur = cur->next) {
+                               for (cur = other; cur; cur = cur->next) {
                                        if (cur->node == node_ptr) {
                                                found = 1;
                                                break;
@@ -485,7 +485,7 @@ void cond_compute_av(struct avtab *ctab, struct avtab_key *key, struct av_decisi
        if (!ctab || !key || !avd)
                return;
 
-       for (node = avtab_search_node(ctab, key); node != NULL;
+       for (node = avtab_search_node(ctab, key); node;
                                node = avtab_search_node_next(node, key->specified)) {
                if ((u16)(AVTAB_ALLOWED|AVTAB_ENABLED) ==
                    (node->key.specified & (AVTAB_ALLOWED|AVTAB_ENABLED)))
index 65b9f8366e9c8635020c934e66f12a4901bbc1d8..53ddb013ae573f8bb053da9fa9416fbcf5ee9701 100644 (file)
@@ -28,7 +28,7 @@ struct cond_expr {
 #define COND_XOR       5 /* bool ^ bool */
 #define COND_EQ                6 /* bool == bool */
 #define COND_NEQ       7 /* bool != bool */
-#define COND_LAST      8
+#define COND_LAST      COND_NEQ
        __u32 expr_type;
        __u32 bool;
        struct cond_expr *next;
index ddc275490af89bddfd1a7e37d60e645fb39de358..68c7348d1acc6628f4c6121207edc34f6a7f707a 100644 (file)
@@ -109,7 +109,7 @@ int ebitmap_netlbl_export(struct ebitmap *ebmap,
        *catmap = c_iter;
        c_iter->startbit = e_iter->startbit & ~(NETLBL_CATMAP_SIZE - 1);
 
-       while (e_iter != NULL) {
+       while (e_iter) {
                for (i = 0; i < EBITMAP_UNIT_NUMS; i++) {
                        unsigned int delta, e_startbit, c_endbit;
 
@@ -197,7 +197,7 @@ int ebitmap_netlbl_import(struct ebitmap *ebmap,
                        }
                }
                c_iter = c_iter->next;
-       } while (c_iter != NULL);
+       } while (c_iter);
        if (e_iter != NULL)
                ebmap->highbit = e_iter->startbit + EBITMAP_SIZE;
        else
index 2e7788e13213002832368b8febed33853c423cea..933e735bb1850d8b7d125f4899124ff8f2af0d0d 100644 (file)
@@ -81,7 +81,7 @@ void *hashtab_search(struct hashtab *h, const void *key)
 
        hvalue = h->hash_value(h, key);
        cur = h->htable[hvalue];
-       while (cur != NULL && h->keycmp(h, key, cur->key) > 0)
+       while (cur && h->keycmp(h, key, cur->key) > 0)
                cur = cur->next;
 
        if (cur == NULL || (h->keycmp(h, key, cur->key) != 0))
@@ -100,7 +100,7 @@ void hashtab_destroy(struct hashtab *h)
 
        for (i = 0; i < h->size; i++) {
                cur = h->htable[i];
-               while (cur != NULL) {
+               while (cur) {
                        temp = cur;
                        cur = cur->next;
                        kfree(temp);
@@ -127,7 +127,7 @@ int hashtab_map(struct hashtab *h,
 
        for (i = 0; i < h->size; i++) {
                cur = h->htable[i];
-               while (cur != NULL) {
+               while (cur) {
                        ret = apply(cur->key, cur->datum, args);
                        if (ret)
                                return ret;
index 77d745da48bb6e4c2153fc3a64852b9c08f80e51..b5407f16c2a4e71b06550beb671ddb9de14591b3 100644 (file)
@@ -283,8 +283,8 @@ int mls_context_to_sid(struct policydb *pol,
                p++;
 
        delim = *p;
-       if (delim != 0)
-               *p++ = 0;
+       if (delim != '\0')
+               *p++ = '\0';
 
        for (l = 0; l < 2; l++) {
                levdatum = hashtab_search(pol->p_levels.table, scontextp);
@@ -302,14 +302,14 @@ int mls_context_to_sid(struct policydb *pol,
                                while (*p && *p != ',' && *p != '-')
                                        p++;
                                delim = *p;
-                               if (delim != 0)
-                                       *p++ = 0;
+                               if (delim != '\0')
+                                       *p++ = '\0';
 
                                /* Separate into range if exists */
                                rngptr = strchr(scontextp, '.');
                                if (rngptr != NULL) {
                                        /* Remove '.' */
-                                       *rngptr++ = 0;
+                                       *rngptr++ = '\0';
                                }
 
                                catdatum = hashtab_search(pol->p_cats.table,
@@ -357,8 +357,8 @@ int mls_context_to_sid(struct policydb *pol,
                                p++;
 
                        delim = *p;
-                       if (delim != 0)
-                               *p++ = 0;
+                       if (delim != '\0')
+                               *p++ = '\0';
                } else
                        break;
        }
index 2391761ae42248806d92b2d2e220f5b1dd7ae6ea..72e4a54973aae503c9c9378aa392750f7f4adb20 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
+#include <linux/audit.h>
 #include "security.h"
 
 #include "policydb.h"
@@ -116,7 +117,12 @@ static struct policydb_compat_info policydb_compat[] = {
                .version        = POLICYDB_VERSION_PERMISSIVE,
                .sym_num        = SYM_NUM,
                .ocon_num       = OCON_NUM,
-       }
+       },
+       {
+               .version        = POLICYDB_VERSION_BOUNDARY,
+               .sym_num        = SYM_NUM,
+               .ocon_num       = OCON_NUM,
+       },
 };
 
 static struct policydb_compat_info *policydb_lookup_compat(int version)
@@ -254,7 +260,9 @@ static int role_index(void *key, void *datum, void *datap)
 
        role = datum;
        p = datap;
-       if (!role->value || role->value > p->p_roles.nprim)
+       if (!role->value
+           || role->value > p->p_roles.nprim
+           || role->bounds > p->p_roles.nprim)
                return -EINVAL;
        p->p_role_val_to_name[role->value - 1] = key;
        p->role_val_to_struct[role->value - 1] = role;
@@ -270,9 +278,12 @@ static int type_index(void *key, void *datum, void *datap)
        p = datap;
 
        if (typdatum->primary) {
-               if (!typdatum->value || typdatum->value > p->p_types.nprim)
+               if (!typdatum->value
+                   || typdatum->value > p->p_types.nprim
+                   || typdatum->bounds > p->p_types.nprim)
                        return -EINVAL;
                p->p_type_val_to_name[typdatum->value - 1] = key;
+               p->type_val_to_struct[typdatum->value - 1] = typdatum;
        }
 
        return 0;
@@ -285,7 +296,9 @@ static int user_index(void *key, void *datum, void *datap)
 
        usrdatum = datum;
        p = datap;
-       if (!usrdatum->value || usrdatum->value > p->p_users.nprim)
+       if (!usrdatum->value
+           || usrdatum->value > p->p_users.nprim
+           || usrdatum->bounds > p->p_users.nprim)
                return -EINVAL;
        p->p_user_val_to_name[usrdatum->value - 1] = key;
        p->user_val_to_struct[usrdatum->value - 1] = usrdatum;
@@ -438,6 +451,14 @@ static int policydb_index_others(struct policydb *p)
                goto out;
        }
 
+       p->type_val_to_struct =
+               kmalloc(p->p_types.nprim * sizeof(*(p->type_val_to_struct)),
+                       GFP_KERNEL);
+       if (!p->type_val_to_struct) {
+               rc = -ENOMEM;
+               goto out;
+       }
+
        if (cond_init_bool_indexes(p)) {
                rc = -ENOMEM;
                goto out;
@@ -625,6 +646,7 @@ void policydb_destroy(struct policydb *p)
        kfree(p->class_val_to_struct);
        kfree(p->role_val_to_struct);
        kfree(p->user_val_to_struct);
+       kfree(p->type_val_to_struct);
 
        avtab_destroy(&p->te_avtab);
 
@@ -932,7 +954,7 @@ static int perm_read(struct policydb *p, struct hashtab *h, void *fp)
        rc = next_entry(key, fp, len);
        if (rc < 0)
                goto bad;
-       key[len] = 0;
+       key[len] = '\0';
 
        rc = hashtab_insert(h, key, perdatum);
        if (rc)
@@ -979,7 +1001,7 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
        rc = next_entry(key, fp, len);
        if (rc < 0)
                goto bad;
-       key[len] = 0;
+       key[len] = '\0';
 
        for (i = 0; i < nel; i++) {
                rc = perm_read(p, comdatum->permissions.table, fp);
@@ -1117,7 +1139,7 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
        rc = next_entry(key, fp, len);
        if (rc < 0)
                goto bad;
-       key[len] = 0;
+       key[len] = '\0';
 
        if (len2) {
                cladatum->comkey = kmalloc(len2 + 1, GFP_KERNEL);
@@ -1128,7 +1150,7 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
                rc = next_entry(cladatum->comkey, fp, len2);
                if (rc < 0)
                        goto bad;
-               cladatum->comkey[len2] = 0;
+               cladatum->comkey[len2] = '\0';
 
                cladatum->comdatum = hashtab_search(p->p_commons.table,
                                                    cladatum->comkey);
@@ -1176,8 +1198,8 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
 {
        char *key = NULL;
        struct role_datum *role;
-       int rc;
-       __le32 buf[2];
+       int rc, to_read = 2;
+       __le32 buf[3];
        u32 len;
 
        role = kzalloc(sizeof(*role), GFP_KERNEL);
@@ -1186,12 +1208,17 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
                goto out;
        }
 
-       rc = next_entry(buf, fp, sizeof buf);
+       if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
+               to_read = 3;
+
+       rc = next_entry(buf, fp, sizeof(buf[0]) * to_read);
        if (rc < 0)
                goto bad;
 
        len = le32_to_cpu(buf[0]);
        role->value = le32_to_cpu(buf[1]);
+       if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
+               role->bounds = le32_to_cpu(buf[2]);
 
        key = kmalloc(len + 1, GFP_KERNEL);
        if (!key) {
@@ -1201,7 +1228,7 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
        rc = next_entry(key, fp, len);
        if (rc < 0)
                goto bad;
-       key[len] = 0;
+       key[len] = '\0';
 
        rc = ebitmap_read(&role->dominates, fp);
        if (rc)
@@ -1236,8 +1263,8 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp)
 {
        char *key = NULL;
        struct type_datum *typdatum;
-       int rc;
-       __le32 buf[3];
+       int rc, to_read = 3;
+       __le32 buf[4];
        u32 len;
 
        typdatum = kzalloc(sizeof(*typdatum), GFP_KERNEL);
@@ -1246,13 +1273,27 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp)
                return rc;
        }
 
-       rc = next_entry(buf, fp, sizeof buf);
+       if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
+               to_read = 4;
+
+       rc = next_entry(buf, fp, sizeof(buf[0]) * to_read);
        if (rc < 0)
                goto bad;
 
        len = le32_to_cpu(buf[0]);
        typdatum->value = le32_to_cpu(buf[1]);
-       typdatum->primary = le32_to_cpu(buf[2]);
+       if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) {
+               u32 prop = le32_to_cpu(buf[2]);
+
+               if (prop & TYPEDATUM_PROPERTY_PRIMARY)
+                       typdatum->primary = 1;
+               if (prop & TYPEDATUM_PROPERTY_ATTRIBUTE)
+                       typdatum->attribute = 1;
+
+               typdatum->bounds = le32_to_cpu(buf[3]);
+       } else {
+               typdatum->primary = le32_to_cpu(buf[2]);
+       }
 
        key = kmalloc(len + 1, GFP_KERNEL);
        if (!key) {
@@ -1262,7 +1303,7 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp)
        rc = next_entry(key, fp, len);
        if (rc < 0)
                goto bad;
-       key[len] = 0;
+       key[len] = '\0';
 
        rc = hashtab_insert(h, key, typdatum);
        if (rc)
@@ -1309,8 +1350,8 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
 {
        char *key = NULL;
        struct user_datum *usrdatum;
-       int rc;
-       __le32 buf[2];
+       int rc, to_read = 2;
+       __le32 buf[3];
        u32 len;
 
        usrdatum = kzalloc(sizeof(*usrdatum), GFP_KERNEL);
@@ -1319,12 +1360,17 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
                goto out;
        }
 
-       rc = next_entry(buf, fp, sizeof buf);
+       if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
+               to_read = 3;
+
+       rc = next_entry(buf, fp, sizeof(buf[0]) * to_read);
        if (rc < 0)
                goto bad;
 
        len = le32_to_cpu(buf[0]);
        usrdatum->value = le32_to_cpu(buf[1]);
+       if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
+               usrdatum->bounds = le32_to_cpu(buf[2]);
 
        key = kmalloc(len + 1, GFP_KERNEL);
        if (!key) {
@@ -1334,7 +1380,7 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
        rc = next_entry(key, fp, len);
        if (rc < 0)
                goto bad;
-       key[len] = 0;
+       key[len] = '\0';
 
        rc = ebitmap_read(&usrdatum->roles, fp);
        if (rc)
@@ -1388,7 +1434,7 @@ static int sens_read(struct policydb *p, struct hashtab *h, void *fp)
        rc = next_entry(key, fp, len);
        if (rc < 0)
                goto bad;
-       key[len] = 0;
+       key[len] = '\0';
 
        levdatum->level = kmalloc(sizeof(struct mls_level), GFP_ATOMIC);
        if (!levdatum->level) {
@@ -1440,7 +1486,7 @@ static int cat_read(struct policydb *p, struct hashtab *h, void *fp)
        rc = next_entry(key, fp, len);
        if (rc < 0)
                goto bad;
-       key[len] = 0;
+       key[len] = '\0';
 
        rc = hashtab_insert(h, key, catdatum);
        if (rc)
@@ -1465,6 +1511,133 @@ static int (*read_f[SYM_NUM]) (struct policydb *p, struct hashtab *h, void *fp)
        cat_read,
 };
 
+static int user_bounds_sanity_check(void *key, void *datum, void *datap)
+{
+       struct user_datum *upper, *user;
+       struct policydb *p = datap;
+       int depth = 0;
+
+       upper = user = datum;
+       while (upper->bounds) {
+               struct ebitmap_node *node;
+               unsigned long bit;
+
+               if (++depth == POLICYDB_BOUNDS_MAXDEPTH) {
+                       printk(KERN_ERR "SELinux: user %s: "
+                              "too deep or looped boundary",
+                              (char *) key);
+                       return -EINVAL;
+               }
+
+               upper = p->user_val_to_struct[upper->bounds - 1];
+               ebitmap_for_each_positive_bit(&user->roles, node, bit) {
+                       if (ebitmap_get_bit(&upper->roles, bit))
+                               continue;
+
+                       printk(KERN_ERR
+                              "SELinux: boundary violated policy: "
+                              "user=%s role=%s bounds=%s\n",
+                              p->p_user_val_to_name[user->value - 1],
+                              p->p_role_val_to_name[bit],
+                              p->p_user_val_to_name[upper->value - 1]);
+
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+static int role_bounds_sanity_check(void *key, void *datum, void *datap)
+{
+       struct role_datum *upper, *role;
+       struct policydb *p = datap;
+       int depth = 0;
+
+       upper = role = datum;
+       while (upper->bounds) {
+               struct ebitmap_node *node;
+               unsigned long bit;
+
+               if (++depth == POLICYDB_BOUNDS_MAXDEPTH) {
+                       printk(KERN_ERR "SELinux: role %s: "
+                              "too deep or looped bounds\n",
+                              (char *) key);
+                       return -EINVAL;
+               }
+
+               upper = p->role_val_to_struct[upper->bounds - 1];
+               ebitmap_for_each_positive_bit(&role->types, node, bit) {
+                       if (ebitmap_get_bit(&upper->types, bit))
+                               continue;
+
+                       printk(KERN_ERR
+                              "SELinux: boundary violated policy: "
+                              "role=%s type=%s bounds=%s\n",
+                              p->p_role_val_to_name[role->value - 1],
+                              p->p_type_val_to_name[bit],
+                              p->p_role_val_to_name[upper->value - 1]);
+
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+static int type_bounds_sanity_check(void *key, void *datum, void *datap)
+{
+       struct type_datum *upper, *type;
+       struct policydb *p = datap;
+       int depth = 0;
+
+       upper = type = datum;
+       while (upper->bounds) {
+               if (++depth == POLICYDB_BOUNDS_MAXDEPTH) {
+                       printk(KERN_ERR "SELinux: type %s: "
+                              "too deep or looped boundary\n",
+                              (char *) key);
+                       return -EINVAL;
+               }
+
+               upper = p->type_val_to_struct[upper->bounds - 1];
+               if (upper->attribute) {
+                       printk(KERN_ERR "SELinux: type %s: "
+                              "bounded by attribute %s",
+                              (char *) key,
+                              p->p_type_val_to_name[upper->value - 1]);
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+static int policydb_bounds_sanity_check(struct policydb *p)
+{
+       int rc;
+
+       if (p->policyvers < POLICYDB_VERSION_BOUNDARY)
+               return 0;
+
+       rc = hashtab_map(p->p_users.table,
+                        user_bounds_sanity_check, p);
+       if (rc)
+               return rc;
+
+       rc = hashtab_map(p->p_roles.table,
+                        role_bounds_sanity_check, p);
+       if (rc)
+               return rc;
+
+       rc = hashtab_map(p->p_types.table,
+                        type_bounds_sanity_check, p);
+       if (rc)
+               return rc;
+
+       return 0;
+}
+
 extern int ss_initialized;
 
 /*
@@ -1523,7 +1696,7 @@ int policydb_read(struct policydb *p, void *fp)
                kfree(policydb_str);
                goto bad;
        }
-       policydb_str[len] = 0;
+       policydb_str[len] = '\0';
        if (strcmp(policydb_str, POLICYDB_STRING)) {
                printk(KERN_ERR "SELinux:  policydb string %s does not match "
                       "my string %s\n", policydb_str, POLICYDB_STRING);
@@ -1961,6 +2134,10 @@ int policydb_read(struct policydb *p, void *fp)
                                goto bad;
        }
 
+       rc = policydb_bounds_sanity_check(p);
+       if (rc)
+               goto bad;
+
        rc = 0;
 out:
        return rc;
index 4253370fda6a22cf7353b0c5c415316fbaa05f8c..55152d498b5342aba65d04c0a6be1b79f784a9f5 100644 (file)
@@ -61,6 +61,7 @@ struct class_datum {
 /* Role attributes */
 struct role_datum {
        u32 value;                      /* internal role value */
+       u32 bounds;                     /* boundary of role */
        struct ebitmap dominates;       /* set of roles dominated by this role */
        struct ebitmap types;           /* set of authorized types for role */
 };
@@ -81,12 +82,15 @@ struct role_allow {
 /* Type attributes */
 struct type_datum {
        u32 value;              /* internal type value */
+       u32 bounds;             /* boundary of type */
        unsigned char primary;  /* primary name? */
+       unsigned char attribute;/* attribute ?*/
 };
 
 /* User attributes */
 struct user_datum {
        u32 value;                      /* internal user value */
+       u32 bounds;                     /* bounds of user */
        struct ebitmap roles;           /* set of authorized roles for user */
        struct mls_range range;         /* MLS range (min - max) for user */
        struct mls_level dfltlevel;     /* default login MLS level for user */
@@ -209,6 +213,7 @@ struct policydb {
        struct class_datum **class_val_to_struct;
        struct role_datum **role_val_to_struct;
        struct user_datum **user_val_to_struct;
+       struct type_datum **type_val_to_struct;
 
        /* type enforcement access vectors and transitions */
        struct avtab te_avtab;
index 8551952ef329bcf62c9fe1516f8a4d181988b543..ab0cc0c7b9444e60a8cf625c0edb1aaa479456ba 100644 (file)
@@ -88,6 +88,11 @@ static u32 latest_granting;
 static int context_struct_to_string(struct context *context, char **scontext,
                                    u32 *scontext_len);
 
+static int context_struct_compute_av(struct context *scontext,
+                                    struct context *tcontext,
+                                    u16 tclass,
+                                    u32 requested,
+                                    struct av_decision *avd);
 /*
  * Return the boolean value of a constraint expression
  * when it is applied to the specified source and target
@@ -273,6 +278,100 @@ mls_ops:
        return s[0];
 }
 
+/*
+ * security_boundary_permission - drops violated permissions
+ * on boundary constraint.
+ */
+static void type_attribute_bounds_av(struct context *scontext,
+                                    struct context *tcontext,
+                                    u16 tclass,
+                                    u32 requested,
+                                    struct av_decision *avd)
+{
+       struct context lo_scontext;
+       struct context lo_tcontext;
+       struct av_decision lo_avd;
+       struct type_datum *source
+               = policydb.type_val_to_struct[scontext->type - 1];
+       struct type_datum *target
+               = policydb.type_val_to_struct[tcontext->type - 1];
+       u32 masked = 0;
+
+       if (source->bounds) {
+               memset(&lo_avd, 0, sizeof(lo_avd));
+
+               memcpy(&lo_scontext, scontext, sizeof(lo_scontext));
+               lo_scontext.type = source->bounds;
+
+               context_struct_compute_av(&lo_scontext,
+                                         tcontext,
+                                         tclass,
+                                         requested,
+                                         &lo_avd);
+               if ((lo_avd.allowed & avd->allowed) == avd->allowed)
+                       return;         /* no masked permission */
+               masked = ~lo_avd.allowed & avd->allowed;
+       }
+
+       if (target->bounds) {
+               memset(&lo_avd, 0, sizeof(lo_avd));
+
+               memcpy(&lo_tcontext, tcontext, sizeof(lo_tcontext));
+               lo_tcontext.type = target->bounds;
+
+               context_struct_compute_av(scontext,
+                                         &lo_tcontext,
+                                         tclass,
+                                         requested,
+                                         &lo_avd);
+               if ((lo_avd.allowed & avd->allowed) == avd->allowed)
+                       return;         /* no masked permission */
+               masked = ~lo_avd.allowed & avd->allowed;
+       }
+
+       if (source->bounds && target->bounds) {
+               memset(&lo_avd, 0, sizeof(lo_avd));
+               /*
+                * lo_scontext and lo_tcontext are already
+                * set up.
+                */
+
+               context_struct_compute_av(&lo_scontext,
+                                         &lo_tcontext,
+                                         tclass,
+                                         requested,
+                                         &lo_avd);
+               if ((lo_avd.allowed & avd->allowed) == avd->allowed)
+                       return;         /* no masked permission */
+               masked = ~lo_avd.allowed & avd->allowed;
+       }
+
+       if (masked) {
+               struct audit_buffer *ab;
+               char *stype_name
+                       = policydb.p_type_val_to_name[source->value - 1];
+               char *ttype_name
+                       = policydb.p_type_val_to_name[target->value - 1];
+               char *tclass_name
+                       = policydb.p_class_val_to_name[tclass - 1];
+
+               /* mask violated permissions */
+               avd->allowed &= ~masked;
+
+               /* notice to userspace via audit message */
+               ab = audit_log_start(current->audit_context,
+                                    GFP_ATOMIC, AUDIT_SELINUX_ERR);
+               if (!ab)
+                       return;
+
+               audit_log_format(ab, "av boundary violation: "
+                                "source=%s target=%s tclass=%s",
+                                stype_name, ttype_name, tclass_name);
+               avc_dump_av(ab, tclass, masked);
+               audit_log_end(ab);
+       }
+}
+
 /*
  * Compute access vectors based on a context structure pair for
  * the permissions in a particular class.
@@ -356,7 +455,7 @@ static int context_struct_compute_av(struct context *scontext,
                        avkey.source_type = i + 1;
                        avkey.target_type = j + 1;
                        for (node = avtab_search_node(&policydb.te_avtab, &avkey);
-                            node != NULL;
+                            node;
                             node = avtab_search_node_next(node, avkey.specified)) {
                                if (node->key.specified == AVTAB_ALLOWED)
                                        avd->allowed |= node->datum.data;
@@ -404,6 +503,14 @@ static int context_struct_compute_av(struct context *scontext,
                                                        PROCESS__DYNTRANSITION);
        }
 
+       /*
+        * If the given source and target types have boundary
+        * constraint, lazy checks have to mask any violated
+        * permission and notice it to userspace via audit.
+        */
+       type_attribute_bounds_av(scontext, tcontext,
+                                tclass, requested, avd);
+
        return 0;
 
 inval_class:
@@ -549,6 +656,69 @@ out:
        return rc;
 }
 
+/*
+ * security_bounded_transition - check whether the given
+ * transition is directed to bounded, or not.
+ * It returns 0, if @newsid is bounded by @oldsid.
+ * Otherwise, it returns error code.
+ *
+ * @oldsid : current security identifier
+ * @newsid : destinated security identifier
+ */
+int security_bounded_transition(u32 old_sid, u32 new_sid)
+{
+       struct context *old_context, *new_context;
+       struct type_datum *type;
+       int index;
+       int rc = -EINVAL;
+
+       read_lock(&policy_rwlock);
+
+       old_context = sidtab_search(&sidtab, old_sid);
+       if (!old_context) {
+               printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n",
+                      __func__, old_sid);
+               goto out;
+       }
+
+       new_context = sidtab_search(&sidtab, new_sid);
+       if (!new_context) {
+               printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n",
+                      __func__, new_sid);
+               goto out;
+       }
+
+       /* type/domain unchaned */
+       if (old_context->type == new_context->type) {
+               rc = 0;
+               goto out;
+       }
+
+       index = new_context->type;
+       while (true) {
+               type = policydb.type_val_to_struct[index - 1];
+               BUG_ON(!type);
+
+               /* not bounded anymore */
+               if (!type->bounds) {
+                       rc = -EPERM;
+                       break;
+               }
+
+               /* @newsid is bounded by @oldsid */
+               if (type->bounds == old_context->type) {
+                       rc = 0;
+                       break;
+               }
+               index = type->bounds;
+       }
+out:
+       read_unlock(&policy_rwlock);
+
+       return rc;
+}
+
+
 /**
  * security_compute_av - Compute access vector decisions.
  * @ssid: source security identifier
@@ -794,7 +964,7 @@ static int string_to_context_struct(struct policydb *pol,
        *p++ = 0;
 
        typdatum = hashtab_search(pol->p_types.table, scontextp);
-       if (!typdatum)
+       if (!typdatum || typdatum->attribute)
                goto out;
 
        ctx->type = typdatum->value;
@@ -1037,7 +1207,7 @@ static int security_compute_sid(u32 ssid,
        /* If no permanent rule, also check for enabled conditional rules */
        if (!avdatum) {
                node = avtab_search_node(&policydb.te_cond_avtab, &avkey);
-               for (; node != NULL; node = avtab_search_node_next(node, specified)) {
+               for (; node; node = avtab_search_node_next(node, specified)) {
                        if (node->key.specified & AVTAB_ENABLED) {
                                avdatum = &node->datum;
                                break;
@@ -2050,7 +2220,7 @@ int security_set_bools(int len, int *values)
                        policydb.bool_val_to_struct[i]->state = 0;
        }
 
-       for (cur = policydb.cond_list; cur != NULL; cur = cur->next) {
+       for (cur = policydb.cond_list; cur; cur = cur->next) {
                rc = evaluate_cond_node(&policydb, cur);
                if (rc)
                        goto out;
@@ -2102,7 +2272,7 @@ static int security_preserve_bools(struct policydb *p)
                if (booldatum)
                        booldatum->state = bvalues[i];
        }
-       for (cur = p->cond_list; cur != NULL; cur = cur->next) {
+       for (cur = p->cond_list; cur; cur = cur->next) {
                rc = evaluate_cond_node(p, cur);
                if (rc)
                        goto out;
index a81ded10412980ea9d4b186233210fec9b696ac2..e817989764cd48dd4061bc49c30c6cb8da357474 100644 (file)
@@ -43,7 +43,7 @@ int sidtab_insert(struct sidtab *s, u32 sid, struct context *context)
        hvalue = SIDTAB_HASH(sid);
        prev = NULL;
        cur = s->htable[hvalue];
-       while (cur != NULL && sid > cur->sid) {
+       while (cur && sid > cur->sid) {
                prev = cur;
                cur = cur->next;
        }
@@ -92,7 +92,7 @@ static struct context *sidtab_search_core(struct sidtab *s, u32 sid, int force)
 
        hvalue = SIDTAB_HASH(sid);
        cur = s->htable[hvalue];
-       while (cur != NULL && sid > cur->sid)
+       while (cur && sid > cur->sid)
                cur = cur->next;
 
        if (force && cur && sid == cur->sid && cur->context.len)
@@ -103,7 +103,7 @@ static struct context *sidtab_search_core(struct sidtab *s, u32 sid, int force)
                sid = SECINITSID_UNLABELED;
                hvalue = SIDTAB_HASH(sid);
                cur = s->htable[hvalue];
-               while (cur != NULL && sid > cur->sid)
+               while (cur && sid > cur->sid)
                        cur = cur->next;
                if (!cur || sid != cur->sid)
                        return NULL;
@@ -136,7 +136,7 @@ int sidtab_map(struct sidtab *s,
 
        for (i = 0; i < SIDTAB_SIZE; i++) {
                cur = s->htable[i];
-               while (cur != NULL) {
+               while (cur) {
                        rc = apply(cur->sid, &cur->context, args);
                        if (rc)
                                goto out;
@@ -155,7 +155,7 @@ static inline u32 sidtab_search_context(struct sidtab *s,
 
        for (i = 0; i < SIDTAB_SIZE; i++) {
                cur = s->htable[i];
-               while (cur != NULL) {
+               while (cur) {
                        if (context_cmp(&cur->context, context))
                                return cur->sid;
                        cur = cur->next;
@@ -242,7 +242,7 @@ void sidtab_destroy(struct sidtab *s)
 
        for (i = 0; i < SIDTAB_SIZE; i++) {
                cur = s->htable[i];
-               while (cur != NULL) {
+               while (cur) {
                        temp = cur;
                        cur = cur->next;
                        context_destroy(&temp->context);
index 4a4477f5afdcd3468074c72ea05aa5697dea4566..31dce559595ad48e732a306c8d759a5ce5adde80 100644 (file)
@@ -178,6 +178,7 @@ u32 smack_to_secid(const char *);
 extern int smack_cipso_direct;
 extern int smack_net_nltype;
 extern char *smack_net_ambient;
+extern char *smack_onlycap;
 
 extern struct smack_known *smack_known;
 extern struct smack_known smack_known_floor;
index f6b5f6eed6dd00f6aab7f9873e26dbb700984063..79ff21ed4c3be11b3f10f974874549617d1141a5 100644 (file)
@@ -157,7 +157,7 @@ int smk_access(char *subject_label, char *object_label, int request)
  *
  * This function checks the current subject label/object label pair
  * in the access rule list and returns 0 if the access is permitted,
- * non zero otherwise. It allows that current my have the capability
+ * non zero otherwise. It allows that current may have the capability
  * to override the rules.
  */
 int smk_curacc(char *obj_label, u32 mode)
@@ -168,6 +168,14 @@ int smk_curacc(char *obj_label, u32 mode)
        if (rc == 0)
                return 0;
 
+       /*
+        * Return if a specific label has been designated as the
+        * only one that gets privilege and current does not
+        * have that label.
+        */
+       if (smack_onlycap != NULL && smack_onlycap != current->security)
+               return rc;
+
        if (capable(CAP_MAC_OVERRIDE))
                return 0;
 
index 271a835fbbe3f72f4e5465cbf84b9b271fa7e77a..e7c642458ec9431b1639935880b6082f21492f6a 100644 (file)
@@ -39,6 +39,7 @@ enum smk_inos {
        SMK_DIRECT      = 6,    /* CIPSO level indicating direct label */
        SMK_AMBIENT     = 7,    /* internet ambient label */
        SMK_NLTYPE      = 8,    /* label scheme to use by default */
+       SMK_ONLYCAP     = 9,    /* the only "capable" label */
 };
 
 /*
@@ -68,6 +69,16 @@ int smack_net_nltype = NETLBL_NLTYPE_CIPSOV4;
  */
 int smack_cipso_direct = SMACK_CIPSO_DIRECT_DEFAULT;
 
+/*
+ * Unless a process is running with this label even
+ * having CAP_MAC_OVERRIDE isn't enough to grant
+ * privilege to violate MAC policy. If no label is
+ * designated (the NULL case) capabilities apply to
+ * everyone. It is expected that the hat (^) label
+ * will be used if any label is used.
+ */
+char *smack_onlycap;
+
 static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT;
 struct smk_list_entry *smack_list;
 
@@ -787,6 +798,85 @@ static const struct file_operations smk_ambient_ops = {
        .write          = smk_write_ambient,
 };
 
+/**
+ * smk_read_onlycap - read() for /smack/onlycap
+ * @filp: file pointer, not actually used
+ * @buf: where to put the result
+ * @cn: maximum to send along
+ * @ppos: where to start
+ *
+ * Returns number of bytes read or error code, as appropriate
+ */
+static ssize_t smk_read_onlycap(struct file *filp, char __user *buf,
+                               size_t cn, loff_t *ppos)
+{
+       char *smack = "";
+       ssize_t rc = -EINVAL;
+       int asize;
+
+       if (*ppos != 0)
+               return 0;
+
+       if (smack_onlycap != NULL)
+               smack = smack_onlycap;
+
+       asize = strlen(smack) + 1;
+
+       if (cn >= asize)
+               rc = simple_read_from_buffer(buf, cn, ppos, smack, asize);
+
+       return rc;
+}
+
+/**
+ * smk_write_onlycap - write() for /smack/onlycap
+ * @filp: file pointer, not actually used
+ * @buf: where to get the data from
+ * @count: bytes sent
+ * @ppos: where to start
+ *
+ * Returns number of bytes written or error code, as appropriate
+ */
+static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
+                                size_t count, loff_t *ppos)
+{
+       char in[SMK_LABELLEN];
+       char *sp = current->security;
+
+       if (!capable(CAP_MAC_ADMIN))
+               return -EPERM;
+
+       /*
+        * This can be done using smk_access() but is done
+        * explicitly for clarity. The smk_access() implementation
+        * would use smk_access(smack_onlycap, MAY_WRITE)
+        */
+       if (smack_onlycap != NULL && smack_onlycap != sp)
+               return -EPERM;
+
+       if (count >= SMK_LABELLEN)
+               return -EINVAL;
+
+       if (copy_from_user(in, buf, count) != 0)
+               return -EFAULT;
+
+       /*
+        * Should the null string be passed in unset the onlycap value.
+        * This seems like something to be careful with as usually
+        * smk_import only expects to return NULL for errors. It
+        * is usually the case that a nullstring or "\n" would be
+        * bad to pass to smk_import but in fact this is useful here.
+        */
+       smack_onlycap = smk_import(in, count);
+
+       return count;
+}
+
+static const struct file_operations smk_onlycap_ops = {
+       .read           = smk_read_onlycap,
+       .write          = smk_write_onlycap,
+};
+
 struct option_names {
        int     o_number;
        char    *o_name;
@@ -919,6 +1009,8 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
                        {"ambient", &smk_ambient_ops, S_IRUGO|S_IWUSR},
                [SMK_NLTYPE]    =
                        {"nltype", &smk_nltype_ops, S_IRUGO|S_IWUSR},
+               [SMK_ONLYCAP]   =
+                       {"onlycap", &smk_onlycap_ops, S_IRUGO|S_IWUSR},
                /* last one */ {""}
        };